传输控制协议(TCP)是互联网中最为关键的通信协议之一。了解TCP协议的细节不仅对于网络工程师至关重要,对于任何涉及网络通信的软件开发人员而言都是必备的知识。本文旨在深入探讨TCP协议,从协议的基本概述到其工作机制,以及如何通过实际代码实现和工具分析来理解其运作。
TCP协议概述
TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它的设计目的是为了提供一个可靠的端到端的数据传输服务,在不可靠的互联网环境中保证数据正确传输。
代码实操与分析
具体流程
代码实现
服务端
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
int main()
{
WSADATA wsaData;
SOCKET serverSocket, clientSocket;
struct sockaddr_in server, client;
int c, recv_size;
char client_message[2000];
// Initialize Winsock
WSAStartup(MAKEWORD(2, 2), &wsaData);
// Create a socket
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
// Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
// Bind
bind(serverSocket, (struct sockaddr *) &server, sizeof(server));
// Listen to incoming connections
listen(serverSocket, 3);
// Accept an incoming connection
std::cout << "Waiting for incoming connections..." << std::endl;
c = sizeof(struct sockaddr_in);
clientSocket = accept(serverSocket, (struct sockaddr *) &client, &c);
std::cout << "Connection accepted" << std::endl;
// Send a message to the client
const char *welcome_message = "Hello, client!";
send(clientSocket, welcome_message, strlen(welcome_message), 0);
// Receive a message from client
recv_size = recv(clientSocket, client_message, 2000, 0);
if (recv_size > 0) {
client_message[recv_size] = '\0';
std::cout << "Client replies: " << client_message << std::endl;
} else {
std::cerr << "recv failed or connection closed by client" << std::endl;
}
// Send "quit" message
const char *quit_message = "quit";
send(clientSocket, quit_message, strlen(quit_message), 0);
// Wait for client to disconnect
recv_size = recv(clientSocket, client_message, 2000, 0);
if (recv_size == 0) {
std::cout << "Client disconnected" << std::endl;
} else {
std::cerr << "Error occurred or unexpected data received" << std::endl;
}
// Cleanup
closesocket(clientSocket);
closesocket(serverSocket);
WSACleanup();
return 0;
}
输出结果
客户端
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET s;
struct sockaddr_in server;
const char * server_address = "127.0.0.1";
char server_reply[2000];
int recv_size;
// Initialising Winsock
WSAStartup(MAKEWORD(2, 2), &wsa);
// Create socket
s = socket(AF_INET, SOCK_STREAM, 0);
server.sin_family = AF_INET;
server.sin_port = htons(8888);
inet_pton(AF_INET, server_address, &server.sin_addr);
// Connect to remote server
connect(s, (struct sockaddr *) &server, sizeof(server));
std::cout << "Connected" << std::endl;
// Receive a reply from the server
recv_size = recv(s, server_reply, 2000, 0);
server_reply[recv_size] = '\0';
std::cout << "Server: " << server_reply << std::endl;
// Send reply
const char *message = "Hello";
send(s, message, strlen(message), 0);
// Receive final message from server
recv_size = recv(s, server_reply, 2000, 0);
server_reply[recv_size] = '\0';
std::cout << "Server: " << server_reply << std::endl;
// Close the socket
closesocket(s);
WSACleanup();
return 0;
}
输出结果
WireShark分析
使用WireShark工具捕获端口号为8888的数据:
分析捕获数据
三次握手
- 第一次握手(SYN)
- 源端口和目的端口:63148 → 8888
- 标志位:[SYN]
- 序列号(Seq):0,初始化序列号。
- 窗口大小(Win):65535,表明客户端的接收窗口。
- 长度(Len):0,无数据传输。
- TCP选项:MSS=65495, WS=256, SACK_PERM,表明最大段大小、窗口缩放和选择性确认的支持。
- 第二次握手(SYN, ACK)
- 源端口和目的端口:8888 → 63148
- 标志位:[SYN, ACK]
- 序列号和确认号:Seq=0, Ack=1,服务器确认客户端的SYN并提出自己的SYN。
- 窗口大小:65535。
- 第三次握手(ACK)
- 源端口和目的端口:63148 → 8888
- 标志位:[ACK]
- 序列号和确认号:Seq=1, Ack=1,客户端确认服务器的SYN。
- 窗口大小:2619648,表示客户端的接收窗口大小已调整。
数据传输
- 服务器向客户端发送数据(PSH, ACK)
- 数据长度:14,服务器发送14字节的数据。
- 客户端确认数据(ACK)
- 确认号:Ack=15,客户端确认接收到15字节的数据。
- 客户端向服务器发送数据(PSH, ACK)
- 数据长度:5,客户端发送5字节的数据。
- 服务器确认数据(ACK)
- 确认号:Ack=6,服务器确认接收到6字节的数据。
- 服务器再次发送数据(PSH, ACK)
- 数据长度:4,服务器发送4字节的数据。
- 客户端确认数据(ACK)
- 确认号:Ack=19,客户端确认接收到总计19字节的数据。
四次挥手
- 客户端发起关闭连接(FIN, ACK)
- 序列号和确认号:Seq=6, Ack=19,客户端请求关闭连接。
- 服务器确认关闭请求(ACK)
- 确认号:Ack=7,服务器确认客户端的关闭请求。
- 服务器发起关闭连接(FIN, ACK)
- 序列号和确认号:Seq=19, Ack=7,服务器同样请求关闭连接。
- 客户端确认服务器的关闭请求(ACK)
- 确认号:Ack=20,客户端确认服务器的关闭请求。
TCP协议首部格式
上图展示了TCP协议首部的格式。
源端口号
源端口号是指发送端的端口号,字段长16位。
目标端口号
目标端口号是指接收端的端口号,字段长16位。
序列号
序列号简单来说就是在一个TCP报文段中第一个字节数据在总发送数据包中的位置,通过这个可以保证数据传输的顺序性和完整性。
字段长32位。
详细说明
序列号初始值
序列号在建立连接时会随机生成一个数值作为序列号的初始值,具体的流程如下:
- 第一次握手:
客户端发送一个SYN(同步)包到服务端。这个SYN包包含了客户端选择的初始序列号(ISN_C)。
上图是WireShark捕捉到第一次握手数据中部分数据,其中红框框住的就是客户端生成的初始化序列号(ISN_C)。
- 第二次握手:
服务端收到客户端的SYN包后,会回复一个SYN-ACK(同步确认)包。这个包包括服务端自己的一个初始序列号(ISN_S),以及对客户端初始序列号的确认号(即ISN_C+1)。
上图是WireShark捕捉到的第二次握手数据中部分数据,其中红框框住的就是服务端生成的初始化序列号(ISN_S),绿框框住的是客户端初始序列号的确认号(第一次握手中ISN_C的值是2977803439,当前确认号是2977803440,即ISN_C+1)。
- 第三次握手:
客户端收到服务端的SYN-ACK包后,发送一个ACK(确认)包给服务端,其中包含的确认号是ISN_S+1。
上图是WireShark捕捉到的第三次握手数据中部分数据,其中红框框住的就是经过服务端确认过的客户端序列号(ISN_C),绿框框住的是服务端初始序列号的确认号(即ISN_S+1)。
序列号回绕
序列号字段占32位,意味着序列号可以在0到2^32-1之间变化。当序列号达到其最大值后,它会发送回绕(wrap around),重新从0开始。
我们先看测试代码:
// 未发送回绕
UINT32 s1 = 100;
UINT32 s2 = 200;
int r1 = s1 - s2; // out: -100
// 发生回绕
UINT32 s3 = 4294967295;
UINT32 s4 = 1;
int r2 = s3 - s4; // out: -2
这里通过无符号整型计算结果转有符号整型时发生溢出,结果将进行二进制位取反,然后加一得到补码,最终得到-2的结果。
所以这里是通过转int类型后判断结果是否小于0,小于0则表示s1在s2的前面,s3在s4的前面。
序列号的作用
- 确保数据顺序:每个TCP段(数据包)都有一个序列号,用于标识从TCP连接的起点开始的数据流中的每个字节的位置。接收方可以通过这些序列号,将接收到的数据段重新组装成正确的顺序。
- 数据重传:如果一个数据包在传输过程中丢失或错误,接收方可以检测到丢失的数据段并请求发送方重传那些数据。序列号使得发送方能够确定需要重传哪些数据。
- 避免重复数据:序列号还帮助接收方识别和丢弃重复的数据段,这可能在网络条件不稳定时发生,当数据包延迟或重传时。
- 建立和维持连接状态:在TCP三次握手过程中,序列号用于同步发送方和接收方,确保双方对连接的开始点有共同的认识。这是建立稳定TCP连接的基础。
确认应答号
确认应答号是指接收方用来告诉发送方其期望接收的下一个序列号,也可以理解是目前为止成功接收的数据字节数加一。
字段长32位。
数据偏移
数据偏移用来指示当前TCP报文段中首部的长度,知道首部的长度就知道了该报文段中实际数据的位置。
字段长4位。
由于数据偏移字段只有4位,因此它的范围是0到15,但首部的长度至少20字节,超出了该字段所能表示的大小。所以,数据偏移字段对应值的单位不是字节,而是4字节,比如该字段为0001,则表示首部长度4字节。
保留
保留字段主要是为了以后扩展时使用,一般设置为0(不做强制要求,不为0也不会影响报文段的收发)。
字段长4位。
控制位
控制位字段长8位,每一位都分别代表一个标志位(控制位)。当对应位置的值为1时,表示该控制位生效。
下面依次介绍控制位的作用:
拥塞控制位:CWR和ECE
CWR(Congestion Window Reduced)
拥塞窗口减小标志位,就是发送端设置该字段来告诉接收端发送端已经减小了拥塞窗口。
ECE(ECN-Echo)
显式拥塞通知回应标志位,就是接收端收到数据后,通过IP数据包头的CE位得知网络发生拥塞,那么接收端在发送TCP确认(ACK)时需要设置ECE标志位来通知发送端网络发生拥塞。
具体场景说明
- 检测拥塞并标记
当中间网络设备(如路由器)检测到网络开始出现拥塞时,会在经过的IP数据包头部设置CE(拥塞经历)位,表明这些数据包经历了拥塞。
- 接收端反应
客户端接收到被标记为CE的数据包。在向发送端发送TCP确认(ACK)时,客户端设置ECE位,用来通知发送端其发送的数据包经历了拥塞。这是客户端对检测到拥塞的第一次响应。
- 发送端接收确认并响应
发送端接收到含有ECE位的确认(ACK)包,理解到其数据在网络中遇到了拥塞。
发送端随后启动其拥塞控制机制,例如减小拥塞窗口。为了通知客户端它已经采取了措施以应对拥塞,发送端在后续发送的数据包中设置CWR位。
- 客户端的最终确认
客户端在收到含有CWR位的数据包后,知道发送端已经对拥塞做出了调整。在这一点上,客户端可以清除其ECE标志,因为已经成功地通知了发送端关于拥塞的问题,而发送端也已经确认并做出了调整。
URG(Urgent Flag)
URG被设置为1时,表示当前报文段中有需要紧急处理的数据,同时也表示紧急指针字段(指向紧急数据的最后一个字节,后面会介绍)有效,通过紧急指针字段的值可以知道紧急数据的末尾在报文段中的具体位置。
ACK(Acknowledgement Flag)
ACK位设置为1时表示确认号字段有效。在TCP连接中,发送端发送数据后,接收端会返回一个确认包,其中ACK标志位被设置为1,表示已经成功接收到指定的数据。
PSH(Push Flag)
PSH位设置为1时表示当前报文段中的数据要立即传给应用层,而不是等待缓冲区填满。
当然,这并不能代表某些报文段不会被设置为1,具体场景具体分析。
RST(Reset Flag)
当RST位被设置为1时,表示TCP连接中出现异常,必须立即重置连接。这通常用于处理错误或同步问题。
SYN
SYN标志位只用于建立连接时的握手阶段(前两次握手)。SYN为1时表示希望建立连接,并在其序列号的字段进行序列号初始值的设定。
FIN
FIN标志位通常用于断开连接。FIN为1时表示后续不再发送数据,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换FIN位置为1的TCP报文段。每个主机又对对方的FIN包进行确认应答以后就可以断开连接。不过,主机收到FIN设置为1的TCP报文段以后不必马上回复一个FIN包,而是可以等到缓冲区中的所有数据都因已成功发送而被自动删除之后再发。
窗口大小
窗口大小字段是接收端用来通知发送端其当前可接受数据量大小的机制。TCP不允许发送端发送超过该大小的数据。不过,如果窗口大小为0,则表示可以发送窗口探测,以了解最新的窗口大小。但这个数据必须是1个字节。
功能和作用
- 流量控制
窗口大小决定了接收方在不发送进一步确认的情况下能够接收的数据总量。这意味着发送方可以根据这个窗口大小发送相应量的数据,并等待接收方的确认。这样可以有效避免因数据量过多而导致接收方处理不过来的情况。
- 动态调整
在TCP连接过程中,接收方可以根据自身的缓冲区空间动态调整窗口大小,这一过程称为滑动窗口协议。
- 避免网络拥堵
通过调整窗口大小,TCP协议能够根据网络的当前状态(如延迟和数据丢失)来优化数据传输,减少拥塞的发生。
校验和
校验和字段用于确保数据在传输过程中的完整性和正确性。
TCP校验和的计算涉及几个步骤:
- 伪首部:
首先构造一个伪首部(不是真正发送的一部分,但用于校验和计算)。伪首部包含了源IP地址、目的IP地址、保留位(总是置为0)、协议号(对TCP来说是6)以及TCP长度(TCP头部和数据的总长度)。
- 添加TCP首部和数据:
将伪首部、TCP头部和数据部分组合在一起。如果组合后的数据长度是奇数个字节,会添加一个额外的0字节,以保证数据以16位(2字节)为单位进行处理。
- 计算和校验:
将上述所有16位长的字进行二进制求和(包括进位)。如果在计算过程中产生了进位,则将进位加到最终的和中。最后将此和取反,得到的结果即为校验和。
- 放置校验和:
计算出的校验和被放置在TCP头部的校验和字段中,然后随着TCP报文段被发送到接收方。
校验过程
接收方在收到TCP段后,也会构造相同的伪首部,并对收到的整个TCP段(包括校验和字段中的值)进行相同的计算。理想情况下,如果数据没有错误,计算结果应该是一个固定的值(通常是全1,即0xFFFF)。
校验和的重要性
TCP校验和非常重要,因为它帮助:
- 检测错误:识别数据在传输过程中由于网络噪声、设备故障或其他原因引入的错误。
- 提高可靠性:通过确保只有未损坏的数据被接收和处理,提高了通信的可靠性。
- 兼容性和灵活性:适用于各种网络环境和传输媒介,即使在底层网络技术变化的情况下也能保持有效性。
紧急指针
紧急指针只有在URG控制位为1时有效。紧急指针字段的数值是当前报文段中紧急数据的尾部位置。
比如一个TCP报文段的序列号是1000,并且该报文段包含100字节的数据。如果紧急指针的值为20,那么从序列号1000开始的20个字节就是紧急数据。
选项
选项字段用于提高TCP的传输性能。TCP选项可以在TCP三次握手过程中协商或在任何后续的TCP报文段中指定,以调整或优化连接的行为。
常见的TCP选项
- 最大报文段大小(MSS):
- 描述:定义了TCP通信中可以接受的最大数据段的大小,不包括TCP首部。
- 目的:在连接建立时协商,以防止数据段因过大而被网络中的设备分片,影响性能。
- 窗口扩展选项(Window Scale):
- 描述:扩展窗口大小字段的能力,允许窗口大小超过原始的16位限制,最多可以增加到1 GB。
- 目的:在高延迟或高带宽的网络环境中提高TCP性能。
- 选择确认(SACK):
- 描述:允许接收方指定已经成功接收的非连续的数据块。
- 目的:提高在丢包环境下的TCP效率,减少不必要的重传。
- 时间戳选项:
- 描述:每个TCP段都附带发送和回复的时间戳。
- 目的:提高TCP的性能表现和可靠性,帮助实现更精确的往返时间(RTT)测量和防止序列号的回绕。
- 无操作(NOP,用于填充):
- 描述:用于填充,确保TCP选项的总长度是32位字的整数倍。
- 目的:保证后续选项的正确对齐。
- 结束列表(End of Option List):
- 描述:表示选项字段的结束。
- 目的:标记选项的结束,这对解析TCP首部至关重要。
WireShark数据分析
第一次握手:
Transmission Control Protocol, Src Port: 63148, Dst Port: 8888, Seq: 0, Len: 0
Source Port: 63148
Destination Port: 8888
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 0]
Sequence Number: 0 (relative sequence number)
Sequence Number (raw): 2977803439
[Next Sequence Number: 1 (relative sequence number)]
Acknowledgment Number: 0
Acknowledgment number (raw): 0
1000 .... = Header Length: 32 bytes (8)
Flags: 0x002 (SYN)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...0 .... = Acknowledgment: Not set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..1. = Syn: Set
.... .... ...0 = Fin: Not set
[TCP Flags: ··········S·]
Window: 65535
[Calculated window size: 65535]
Checksum: 0xff57 [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
Options: (12 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), SACK permitted
[Timestamps]
第二次握手:
Transmission Control Protocol, Src Port: 8888, Dst Port: 63148, Seq: 0, Ack: 1, Len: 0
Source Port: 8888
Destination Port: 63148
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 0]
Sequence Number: 0 (relative sequence number)
Sequence Number (raw): 4166461748
[Next Sequence Number: 1 (relative sequence number)]
Acknowledgment Number: 1 (relative ack number)
Acknowledgment number (raw): 2977803440
1000 .... = Header Length: 32 bytes (8)
Flags: 0x012 (SYN, ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..1. = Syn: Set
.... .... ...0 = Fin: Not set
[TCP Flags: ·······A··S·]
Window: 65535
[Calculated window size: 65535]
Checksum: 0xddba [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
Options: (12 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), SACK permitted
[Timestamps]
[SEQ/ACK analysis]
第三次握手:
Transmission Control Protocol, Src Port: 63148, Dst Port: 8888, Seq: 1, Ack: 1, Len: 0
Source Port: 63148
Destination Port: 8888
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 0]
Sequence Number: 1 (relative sequence number)
Sequence Number (raw): 2977803440
[Next Sequence Number: 1 (relative sequence number)]
Acknowledgment Number: 1 (relative ack number)
Acknowledgment number (raw): 4166461749
0101 .... = Header Length: 20 bytes (5)
Flags: 0x010 (ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...0 = Fin: Not set
[TCP Flags: ·······A····]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0xf0b8 [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]
服务端发送数据Hello, client!
:
Transmission Control Protocol, Src Port: 8888, Dst Port: 63148, Seq: 1, Ack: 1, Len: 14
Source Port: 8888
Destination Port: 63148
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 14]
Sequence Number: 1 (relative sequence number)
Sequence Number (raw): 4166461749
[Next Sequence Number: 15 (relative sequence number)]
Acknowledgment Number: 1 (relative ack number)
Acknowledgment number (raw): 2977803440
0101 .... = Header Length: 20 bytes (5)
Flags: 0x018 (PSH, ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 1... = Push: Set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...0 = Fin: Not set
[TCP Flags: ·······AP···]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0x6648 [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]
TCP payload (14 bytes)
客户端确认应答:
Transmission Control Protocol, Src Port: 63148, Dst Port: 8888, Seq: 1, Ack: 15, Len: 0
Source Port: 63148
Destination Port: 8888
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 0]
Sequence Number: 1 (relative sequence number)
Sequence Number (raw): 2977803440
[Next Sequence Number: 1 (relative sequence number)]
Acknowledgment Number: 15 (relative ack number)
Acknowledgment number (raw): 4166461763
0101 .... = Header Length: 20 bytes (5)
Flags: 0x010 (ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...0 = Fin: Not set
[TCP Flags: ·······A····]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0xf0aa [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]
客户端发送数据Hello
:
Transmission Control Protocol, Src Port: 63148, Dst Port: 8888, Seq: 1, Ack: 15, Len: 5
Source Port: 63148
Destination Port: 8888
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 5]
Sequence Number: 1 (relative sequence number)
Sequence Number (raw): 2977803440
[Next Sequence Number: 6 (relative sequence number)]
Acknowledgment Number: 15 (relative ack number)
Acknowledgment number (raw): 4166461763
0101 .... = Header Length: 20 bytes (5)
Flags: 0x018 (PSH, ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 1... = Push: Set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...0 = Fin: Not set
[TCP Flags: ·······AP···]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0xcccb [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]
TCP payload (5 bytes)
服务端确认应答:
Transmission Control Protocol, Src Port: 8888, Dst Port: 63148, Seq: 15, Ack: 6, Len: 0
Source Port: 8888
Destination Port: 63148
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 0]
Sequence Number: 15 (relative sequence number)
Sequence Number (raw): 4166461763
[Next Sequence Number: 15 (relative sequence number)]
Acknowledgment Number: 6 (relative ack number)
Acknowledgment number (raw): 2977803445
0101 .... = Header Length: 20 bytes (5)
Flags: 0x010 (ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...0 = Fin: Not set
[TCP Flags: ·······A····]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0xf0a5 [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]
服务端发送数据quit
:
Transmission Control Protocol, Src Port: 8888, Dst Port: 63148, Seq: 15, Ack: 6, Len: 4
Source Port: 8888
Destination Port: 63148
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 4]
Sequence Number: 15 (relative sequence number)
Sequence Number (raw): 4166461763
[Next Sequence Number: 19 (relative sequence number)]
Acknowledgment Number: 6 (relative ack number)
Acknowledgment number (raw): 2977803445
0101 .... = Header Length: 20 bytes (5)
Flags: 0x018 (PSH, ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 1... = Push: Set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...0 = Fin: Not set
[TCP Flags: ·······AP···]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0x15b0 [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]
TCP payload (4 bytes)
客户端确认应答:
Transmission Control Protocol, Src Port: 63148, Dst Port: 8888, Seq: 6, Ack: 19, Len: 0
Source Port: 63148
Destination Port: 8888
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 0]
Sequence Number: 6 (relative sequence number)
Sequence Number (raw): 2977803445
[Next Sequence Number: 6 (relative sequence number)]
Acknowledgment Number: 19 (relative ack number)
Acknowledgment number (raw): 4166461767
0101 .... = Header Length: 20 bytes (5)
Flags: 0x010 (ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...0 = Fin: Not set
[TCP Flags: ·······A····]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0xf0a1 [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]
第一次挥手:
Transmission Control Protocol, Src Port: 63148, Dst Port: 8888, Seq: 6, Ack: 19, Len: 0
Source Port: 63148
Destination Port: 8888
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 0]
Sequence Number: 6 (relative sequence number)
Sequence Number (raw): 2977803445
[Next Sequence Number: 7 (relative sequence number)]
Acknowledgment Number: 19 (relative ack number)
Acknowledgment number (raw): 4166461767
0101 .... = Header Length: 20 bytes (5)
Flags: 0x011 (FIN, ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...1 = Fin: Set
[TCP Flags: ·······A···F]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0xf0a0 [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
第二次挥手:
Transmission Control Protocol, Src Port: 8888, Dst Port: 63148, Seq: 19, Ack: 7, Len: 0
Source Port: 8888
Destination Port: 63148
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 0]
Sequence Number: 19 (relative sequence number)
Sequence Number (raw): 4166461767
[Next Sequence Number: 19 (relative sequence number)]
Acknowledgment Number: 7 (relative ack number)
Acknowledgment number (raw): 2977803446
0101 .... = Header Length: 20 bytes (5)
Flags: 0x010 (ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...0 = Fin: Not set
[TCP Flags: ·······A····]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0xf0a0 [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]
第三次挥手:
Transmission Control Protocol, Src Port: 8888, Dst Port: 63148, Seq: 19, Ack: 7, Len: 0
Source Port: 8888
Destination Port: 63148
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 0]
Sequence Number: 19 (relative sequence number)
Sequence Number (raw): 4166461767
[Next Sequence Number: 20 (relative sequence number)]
Acknowledgment Number: 7 (relative ack number)
Acknowledgment number (raw): 2977803446
0101 .... = Header Length: 20 bytes (5)
Flags: 0x011 (FIN, ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...1 = Fin: Set
[TCP Flags: ·······A···F]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0xf09f [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
第四次挥手:
Transmission Control Protocol, Src Port: 63148, Dst Port: 8888, Seq: 7, Ack: 20, Len: 0
Source Port: 63148
Destination Port: 8888
[Stream index: 0]
[Conversation completeness: Complete, WITH_DATA (31)]
[TCP Segment Len: 0]
Sequence Number: 7 (relative sequence number)
Sequence Number (raw): 2977803446
[Next Sequence Number: 7 (relative sequence number)]
Acknowledgment Number: 20 (relative ack number)
Acknowledgment number (raw): 4166461768
0101 .... = Header Length: 20 bytes (5)
Flags: 0x010 (ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Accurate ECN: Not set
.... 0... .... = Congestion Window Reduced: Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...0 = Fin: Not set
[TCP Flags: ·······A····]
Window: 10233
[Calculated window size: 2619648]
[Window size scaling factor: 256]
Checksum: 0xf09f [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
[Timestamps]
[SEQ/ACK analysis]