ฉันได้เรียนรู้ว่าบิต ACK ในแพ็กเก็ต TCP ถูกตั้งค่าเมื่อตอบกลับข้อความที่เพียร์ส่ง ซึ่งหมายความว่า "ตกลง ฉันได้รับแพ็กเก็ตทั้งหมดที่มีหมายเลขลำดับน้อยกว่า แล้ว ตอนนี้ฉันคาดว่าจะได้รับแพ็กเก็ตแล้ว โดยมีหมายเลขลำดับเท่ากับ " แต่จากประสบการณ์ของฉัน ดูเหมือนว่าบิต ACK จะถูกตั้งค่าไว้ในแพ็กเก็ต TCP เกือบทั้งหมดเสมอ คาดว่าจะเป็นแพ็กเก็ต SYN แรก
ประสบการณ์ของฉันเป็นดังนี้:
- เซิร์ฟเวอร์จะฟังพอร์ต
SERVER_SOCK
(ซึ่งก็คือ 32413) - ลูกค้าจะเชื่อมต่อกับเซิร์ฟเวอร์
- เซิร์ฟเวอร์จะส่งข้อความ ("สวัสดี") ไปยังลูกค้า
- ลูกค้าอ่านข้อความแล้วฉันกด Enter เพื่อปิดไคลเอนต์
- ฉันกด Enter เพื่อปิดเซิร์ฟเวอร์
รหัส C สำหรับประสบการณ์ของฉันมีดังต่อไปนี้:
ลูกค้า
#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;
}
เซิร์ฟเวอร์
#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;
}
ฉันใช้ wireshark เพื่อจับแพ็กเก็ต และผลลัพธ์จะแสดงดังนี้:
อย่างที่คุณเห็น ทุกแพ็กเก็ตยกเว้นแพ็กเก็ตแรกจะมีการตั้งค่าบิต ACK ไว้ แล้วทำไมล่ะ? แพ็กเก็ต #4, #6 และ #8 รับทราบอะไรบ้าง