0

I learned that the ACK bit in a TCP packet is set when replying to a message sent by the peer, meaning that "OK, I've received all the packets with their sequence numbers smaller than . Now I'm expecting to receive a packet with its sequence number equal to ". But from my experience, it seems that the ACK bit is always set in almost all the TCP packets, expect the first SYN packet.

My experience goes as follows:

  1. The server will listen on port SERVER_SOCK (which is 32413).
  2. The client will connect to the server.
  3. The server will send a message ("hello") to the client.
  4. The client reads the message, and then I press enter to close the client.
  5. I press enter to close the server.

The C code for my experience are listed as follows:

Client

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SERVER_SOCK 32413

int main() {
    // Create socket
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    // Connect to server
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(SERVER_SOCK);
    connect(sock, (struct sockaddr*) &server_addr, sizeof(server_addr));
    printf("Connected\n");

    // Read message from server
    char msg[32] = {0};
    read(sock, msg, 32);
    printf("%s\n", msg);

    printf("Press ENTER to call close()");
    getchar();
    close(sock);
    return 0;
}

Server

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SERVER_SOCK 32413
#define LISTEN_BACKLOG 3

int main() {
    int server_sock, client_sock;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_len = sizeof(client_addr);

    // Create socket
    server_sock = socket(AF_INET, SOCK_STREAM, 0);

    // Set address and port
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(SERVER_SOCK);

    // Bind to port and begin listening
    bind(server_sock, (struct sockaddr*) &server_addr, sizeof(server_addr));
    listen(server_sock, LISTEN_BACKLOG);
    printf("Server is listening\n");

    // Accept client socket
    client_sock = accept(server_sock, (struct sockaddr*) &client_addr, &client_len);
    printf("Connection accepted\n");

    // Send message to client
    send(client_sock, "hello", 5, 0);

    printf("Press enter to call close()");
    getchar();
    close(client_sock);
    close(server_sock);

    return 0;
}

I use wireshark to capture the packets, and the result is shown as follows:

wireshark result

As you can see, every packet except the first one has their ACK bits set. So why? What are the packets #4, #6 and #8 acknowledging to?

TsReaper
  • 845
  • 7
  • 19
  • It's not the same question. What I ask is that why the ACK bit of almost every packet is set, including the packets carrying data to others. What the "possible duplicate" question asks is that if a SYN is needed each time one trys to send data to its peer. The answer to the "possible duplicate" question cannot explain the phenomenon I'm faced with. – TsReaper Apr 12 '18 at 16:38
  • 1
    That's true, but I think the answer to that question also answers your question, particularly this bit: "An ACK is simply a flag and field in a TCP header. Sending one requires at least a header's worth of bandwidth, plus whatever the lower layers tack on. But data segments already include all that...so if you're sending data, you can send an ACK at the same time for free." And the paragraph and diagram below that. – TypeIA Apr 12 '18 at 16:42
  • 1
    A ack conveys information to the sender about what data has been successfully delivered. Duplicate acks are used for fast retransmit/recovery. So setting ack flag only when new data is received would lead to poor performance. Also it costs nothing to set the ack bit. – FormerNcp Apr 14 '18 at 14:10

0 Answers0