深入理解TCP协议格式(WireShark分析)

传输控制协议(TCP)是互联网中最为关键的通信协议之一。了解TCP协议的细节不仅对于网络工程师至关重要,对于任何涉及网络通信的软件开发人员而言都是必备的知识。本文旨在深入探讨TCP协议,从协议的基本概述到其工作机制,以及如何通过实际代码实现和工具分析来理解其运作。

TCP协议概述

TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它的设计目的是为了提供一个可靠的端到端的数据传输服务,在不可靠的互联网环境中保证数据正确传输。

代码实操与分析

具体流程

TCP流程.png

代码实现

注意:下面代码为测试代码,没有异常处理

服务端

#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;
}

输出结果

image.png

客户端

#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;
}

输出结果

image.png

WireShark分析

使用WireShark工具捕获端口号为8888的数据:
image.png

分析捕获数据

我们按照捕获数据的顺序依次解读。

三次握手
  1. 第一次握手(SYN)
  • 源端口和目的端口:63148 → 8888
  • 标志位:[SYN]
  • 序列号(Seq):0,初始化序列号。
  • 窗口大小(Win):65535,表明客户端的接收窗口。
  • 长度(Len):0,无数据传输。
  • TCP选项:MSS=65495, WS=256, SACK_PERM,表明最大段大小、窗口缩放和选择性确认的支持。
  1. 第二次握手(SYN, ACK)
  • 源端口和目的端口:8888 → 63148
  • 标志位:[SYN, ACK]
  • 序列号和确认号:Seq=0, Ack=1,服务器确认客户端的SYN并提出自己的SYN。
  • 窗口大小:65535。
  1. 第三次握手(ACK)
  • 源端口和目的端口:63148 → 8888
  • 标志位:[ACK]
  • 序列号和确认号:Seq=1, Ack=1,客户端确认服务器的SYN。
  • 窗口大小:2619648,表示客户端的接收窗口大小已调整。
数据传输
  1. 服务器向客户端发送数据(PSH, ACK)
  • 数据长度:14,服务器发送14字节的数据。
  1. 客户端确认数据(ACK)
  • 确认号:Ack=15,客户端确认接收到15字节的数据。
  1. 客户端向服务器发送数据(PSH, ACK)
  • 数据长度:5,客户端发送5字节的数据。
  1. 服务器确认数据(ACK)
  • 确认号:Ack=6,服务器确认接收到6字节的数据。
  1. 服务器再次发送数据(PSH, ACK)
  • 数据长度:4,服务器发送4字节的数据。
  1. 客户端确认数据(ACK)
  • 确认号:Ack=19,客户端确认接收到总计19字节的数据。
四次挥手
  1. 客户端发起关闭连接(FIN, ACK)
  • 序列号和确认号:Seq=6, Ack=19,客户端请求关闭连接。
  1. 服务器确认关闭请求(ACK)
  • 确认号:Ack=7,服务器确认客户端的关闭请求。
  1. 服务器发起关闭连接(FIN, ACK)
  • 序列号和确认号:Seq=19, Ack=7,服务器同样请求关闭连接。
  1. 客户端确认服务器的关闭请求(ACK)
  • 确认号:Ack=20,客户端确认服务器的关闭请求。

TCP协议首部格式

TCP首部格式.png
上图展示了TCP协议首部的格式。

源端口号

源端口号是指发送端的端口号,字段长16位。

目标端口号

目标端口号是指接收端的端口号,字段长16位。

序列号

序列号简单来说就是在一个TCP报文段中第一个字节数据在总发送数据包中的位置,通过这个可以保证数据传输的顺序性和完整性。
字段长32位。

详细说明

序列号初始值

序列号在建立连接时会随机生成一个数值作为序列号的初始值,具体的流程如下:

  1. 第一次握手

客户端发送一个SYN(同步)包到服务端。这个SYN包包含了客户端选择的初始序列号(ISN_C)。
image.png
上图是WireShark捕捉到第一次握手数据中部分数据,其中红框框住的就是客户端生成的初始化序列号(ISN_C)。

  1. 第二次握手

服务端收到客户端的SYN包后,会回复一个SYN-ACK(同步确认)包。这个包包括服务端自己的一个初始序列号(ISN_S),以及对客户端初始序列号的确认号(即ISN_C+1)。
image.png
上图是WireShark捕捉到的第二次握手数据中部分数据,其中红框框住的就是服务端生成的初始化序列号(ISN_S),绿框框住的是客户端初始序列号的确认号(第一次握手中ISN_C的值是2977803439,当前确认号是2977803440,即ISN_C+1)。

  1. 第三次握手

客户端收到服务端的SYN-ACK包后,发送一个ACK(确认)包给服务端,其中包含的确认号是ISN_S+1。
image.png
上图是WireShark捕捉到的第三次握手数据中部分数据,其中红框框住的就是经过服务端确认过的客户端序列号(ISN_C),绿框框住的是服务端初始序列号的确认号(即ISN_S+1)。

注意
因为TCP是一个全双工协议,当客户端发送数据时,对应的序列号使用的是客户端的初始序列号,而服务端发送数据时,使用的是服务端的初始序列号。

序列号回绕

序列号字段占32位,意味着序列号可以在0到2^32-1之间变化。当序列号达到其最大值后,它会发送回绕(wrap around),重新从0开始。

既然是从0回绕了,那TCP是如何保证数据的顺序的呢?

我们先看测试代码:

// 未发送回绕
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标志位来通知发送端网络发生拥塞。

具体场景说明
  1. 检测拥塞并标记

当中间网络设备(如路由器)检测到网络开始出现拥塞时,会在经过的IP数据包头部设置CE(拥塞经历)位,表明这些数据包经历了拥塞。

  1. 接收端反应

客户端接收到被标记为CE的数据包。在向发送端发送TCP确认(ACK)时,客户端设置ECE位,用来通知发送端其发送的数据包经历了拥塞。这是客户端对检测到拥塞的第一次响应。

  1. 发送端接收确认并响应

发送端接收到含有ECE位的确认(ACK)包,理解到其数据在网络中遇到了拥塞。
发送端随后启动其拥塞控制机制,例如减小拥塞窗口。为了通知客户端它已经采取了措施以应对拥塞,发送端在后续发送的数据包中设置CWR位。

  1. 客户端的最终确认

客户端在收到含有CWR位的数据包后,知道发送端已经对拥塞做出了调整。在这一点上,客户端可以清除其ECE标志,因为已经成功地通知了发送端关于拥塞的问题,而发送端也已经确认并做出了调整。

URG(Urgent Flag)

URG被设置为1时,表示当前报文段中有需要紧急处理的数据,同时也表示紧急指针字段(指向紧急数据的最后一个字节,后面会介绍)有效,通过紧急指针字段的值可以知道紧急数据的末尾在报文段中的具体位置。

ACK(Acknowledgement Flag)

ACK位设置为1时表示确认号字段有效。在TCP连接中,发送端发送数据后,接收端会返回一个确认包,其中ACK标志位被设置为1,表示已经成功接收到指定的数据。

PSH(Push Flag)

PSH位设置为1时表示当前报文段中的数据要立即传给应用层,而不是等待缓冲区填满。

在默认情况下,报文段的PSH位设置为1有两种情况:

  1. 数据被拆分成多个报文段时,通常只有最后一个报文段的PSH设置为1,因为应用层需要拿到所有完整的数据才能进行处理
  2. 只需单个报文段传输时,该报文段的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个字节。

功能和作用

  1. 流量控制

窗口大小决定了接收方在不发送进一步确认的情况下能够接收的数据总量。这意味着发送方可以根据这个窗口大小发送相应量的数据,并等待接收方的确认。这样可以有效避免因数据量过多而导致接收方处理不过来的情况。

  1. 动态调整

在TCP连接过程中,接收方可以根据自身的缓冲区空间动态调整窗口大小,这一过程称为滑动窗口协议

  1. 避免网络拥堵

通过调整窗口大小,TCP协议能够根据网络的当前状态(如延迟和数据丢失)来优化数据传输,减少拥塞的发生。

校验和

校验和字段用于确保数据在传输过程中的完整性和正确性。
TCP校验和的计算涉及几个步骤:

  1. 伪首部

首先构造一个伪首部(不是真正发送的一部分,但用于校验和计算)。伪首部包含了源IP地址、目的IP地址、保留位(总是置为0)、协议号(对TCP来说是6)以及TCP长度(TCP头部和数据的总长度)。

  1. 添加TCP首部和数据

将伪首部、TCP头部和数据部分组合在一起。如果组合后的数据长度是奇数个字节,会添加一个额外的0字节,以保证数据以16位(2字节)为单位进行处理。

  1. 计算和校验

将上述所有16位长的字进行二进制求和(包括进位)。如果在计算过程中产生了进位,则将进位加到最终的和中。最后将此和取反,得到的结果即为校验和。

  1. 放置校验和

计算出的校验和被放置在TCP头部的校验和字段中,然后随着TCP报文段被发送到接收方。

校验过程

接收方在收到TCP段后,也会构造相同的伪首部,并对收到的整个TCP段(包括校验和字段中的值)进行相同的计算。理想情况下,如果数据没有错误,计算结果应该是一个固定的值(通常是全1,即0xFFFF)。

校验和的重要性

TCP校验和非常重要,因为它帮助:

  • 检测错误:识别数据在传输过程中由于网络噪声、设备故障或其他原因引入的错误。
  • 提高可靠性:通过确保只有未损坏的数据被接收和处理,提高了通信的可靠性。
  • 兼容性和灵活性:适用于各种网络环境和传输媒介,即使在底层网络技术变化的情况下也能保持有效性。

紧急指针

紧急指针只有在URG控制位为1时有效。紧急指针字段的数值是当前报文段中紧急数据的尾部位置。
比如一个TCP报文段的序列号是1000,并且该报文段包含100字节的数据。如果紧急指针的值为20,那么从序列号1000开始的20个字节就是紧急数据。

选项

选项字段用于提高TCP的传输性能。TCP选项可以在TCP三次握手过程中协商或在任何后续的TCP报文段中指定,以调整或优化连接的行为。

常见的TCP选项

  1. 最大报文段大小(MSS)
  • 描述:定义了TCP通信中可以接受的最大数据段的大小,不包括TCP首部。
  • 目的:在连接建立时协商,以防止数据段因过大而被网络中的设备分片,影响性能。
  1. 窗口扩展选项(Window Scale)
  • 描述:扩展窗口大小字段的能力,允许窗口大小超过原始的16位限制,最多可以增加到1 GB。
  • 目的:在高延迟或高带宽的网络环境中提高TCP性能。
  1. 选择确认(SACK)
  • 描述:允许接收方指定已经成功接收的非连续的数据块。
  • 目的:提高在丢包环境下的TCP效率,减少不必要的重传。
  1. 时间戳选项
  • 描述:每个TCP段都附带发送和回复的时间戳。
  • 目的:提高TCP的性能表现和可靠性,帮助实现更精确的往返时间(RTT)测量和防止序列号的回绕。
  1. 无操作(NOP,用于填充)
  • 描述:用于填充,确保TCP选项的总长度是32位字的整数倍。
  • 目的:保证后续选项的正确对齐。
  1. 结束列表(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]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/778898.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多维度多场景文档门户,鸿翼ECM文档云打造文档管理新范式

​在现代企业运营中&#xff0c;内容协作的效率直接影响到组织的整体表现和竞争力。传统的文档管理系统都是通过目录结构的方式进行文件管理&#xff0c;在实际业务中无法满足用户多视角、多维度、多场景的文档业务需求。因此&#xff0c;搭建结合文档体系的业务门户是许多企业…

AI绘画【光影模型】,穿越赛博迷雾,重塑光影艺术本真魅力

有时候是不是觉得单纯依靠大模型产生的图片作品光线方面平平无奇&#xff0c;依靠提示词&#xff0c;各种权重的调整费了九牛二虎之力才抽到一张感觉还算满意的作品。这个时候我们可以考虑结合相关Lora来进行。今天带来了一款光影氛围灯效果Lora——None-光染摄影&#xff0c;该…

进程的概念

一.进程和程序的理解 首先抛出结论&#xff1a;进程是动态的&#xff0c;暂时存在于内存中&#xff0c;进程是程序的一次执行&#xff0c;而进程总是对应至少一个特定的程序。 程序是静态的&#xff0c;永久的存在于磁盘中。 程序是什么呢&#xff1f;程序其实就是存放在我们…

Windows如何查看端口是否占用,并结束端口进程

需求与问题&#xff1a;前后端配置了跨域操作&#xff0c;但是仍然报错&#xff0c;可以考虑端口被两个程序占用&#xff0c;找不到正确端口或者后端接口书写是否规范&#xff0c;特别是利用Python Flask书写时要保证缩进是否正确&#xff01; Windows操作系统中&#xff0c;查…

Matlab中collectPlaneWave函数的应用

查看文档如下&#xff1a; 可以看出最多5个参数&#xff0c;分别是阵列对象&#xff0c;信号幅度&#xff0c;入射角度&#xff0c;信号频率&#xff0c;光速。 在下面的代码中&#xff0c;我们先创建一个3阵元的阵列&#xff0c;位置为&#xff1a;&#xff08;-1,0,0&#x…

代码随想录算法训练Day57|LeetCode200-岛屿数量、LeetCode695-岛屿的最大面积

岛屿数量 题目描述 力扣200-岛屿数量 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此…

设计模式之单例模式(Java)

单例模式实现方式&#xff1a;懒汉式、饿汉式、双重检查、枚举、静态内部类&#xff1b; 懒汉式&#xff1a; /*** 懒汉式单例模式* author: 小手WA凉* create: 2024-07-06*/ public class LazySingleton implements Serializable {private static LazySingleton lazySinglet…

操作系统中的权限说明

什么是权限 权限在操作系统中是一个重要的功能&#xff0c;它允许你控制谁可以读取、写入或执行某个文件。不同的操作系统和文件系统可能有不同的权限模型&#xff0c;但在类Unix系统&#xff08;如Linux和macOS&#xff09;中&#xff0c;文件权限通常由三部分组成&#xff1a…

提升系统稳定性:熔断、降级和限流策略详解

文章目录 前言一、熔断&#xff08;Circuit Breaker&#xff09;二、降级&#xff08;Degradation&#xff09;三、限流&#xff08;Rate Limiting&#xff09;四、应用案例五、小结推荐阅读 前言 随着互联网业务的快速发展&#xff0c;系统稳定性和高可用性成为现代分布式系统…

Spring源码十三:非懒加载单例Bean

上一篇Spring源码十二&#xff1a;事件发布源码跟踪中&#xff0c;我们介绍了Spring中是如何使用观察者设计模式的思想来实现事件驱动开发的&#xff1a;实际上就是将所有监听器注册到广播器中&#xff0c;并通过监听该事件的监听器来处理时间的。结合前面十二篇文章我们将Spri…

电表读数检测数据集VOC+YOLO格式18156张12类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;18156 标注数量(xml文件个数)&#xff1a;18156 标注数量(txt文件个数)&#xff1a;18156 标…

cs224n作业4

NMT结构图&#xff1a;&#xff08;具体结构图&#xff09; LSTM基础知识 nmt_model.py&#xff1a; 参考文章&#xff1a;LSTM输出结构描述 #!/usr/bin/env python3 # -*- coding: utf-8 -*-""" CS224N 2020-21: Homework 4 nmt_model.py: NMT Model Penchen…

【0基础学爬虫】爬虫基础之scrapy的使用

【0基础学爬虫】爬虫基础之scrapy的使用 大数据时代&#xff0c;各行各业对数据采集的需求日益增多&#xff0c;网络爬虫的运用也更为广泛&#xff0c;越来越多的人开始学习网络爬虫这项技术&#xff0c;K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章&#xff0c;为实现从易到…

九浅一深Jemalloc5.3.0 -- ④浅*配置

目前市面上有不少分析Jemalloc老版本的博文&#xff0c;但最新版本5.3.0却少之又少。而且5.3.0的架构与5之前的版本有较大不同&#xff0c;本着“与时俱进”、“由浅入深”的宗旨&#xff0c;我将逐步分析最新release版本Jemalloc5.3.0的实现。 另外&#xff0c;单讲实现代码是…

多功能工具网站

江下科技在线应用-免费PDF转换成Word-word转pdf-无需下载安装 (onlinedo.cn)https://www.onlinedo.cn/

荞面打造的甜蜜魔法:甜甜圈

食家巷荞面甜甜圈是一款具有特色的美食。它以荞面为主要原料&#xff0c;相较于普通面粉&#xff0c;荞面具有更高的营养价值&#xff0c;富含膳食纤维、维生素和矿物质。荞面甜甜圈的口感可能会更加扎实和有嚼劲&#xff0c;同时带着荞面特有的谷物香气。在制作过程中&#xf…

vue侦听器watch()

侦听器watch&#xff08;&#xff09; 侦听器侦听数据变化&#xff0c;我们可以使用watch 选项在每次响应式属性变化时触发一个函数。 <template><h3>侦听器watch</h3><hr> <p>{{nessage}}</p> <button click"exchage">…

缓存-缓存的使用与基本详解

1.缓存使用 为了系统性能的提升&#xff0c;我们一般都会将部分数据放入缓存中&#xff0c;加速访问。而db承担数据落盘工作。 哪些数据适合放入缓存&#xff1f; 即时性、数据一致性要求不高的访问量大且更新频率不高的数据&#xff08;读多&#xff0c;写少&#xff09; …

IDEA安装IDE Eval Reset插件,30天自动续期,无限激活

第一步&#xff1a; 下载idea 注意&#xff1a;版本要是2021.2.2以下 第二步&#xff1a;快捷键CtrlAlts打开设置 第三步&#xff1a;打开下图中蓝色按钮 第四步&#xff1a;点击弹窗的 “” &#xff0c;并输入 plugins.zhile.io 点击 “ok” 第五步&#xff1a;搜索IDE Ea…

Android ViewPostImeInputStage输入事件处理

InputDispatcher向InputChannel使用socket写入输入事件&#xff0c;触发InputEventReceiver调用来接收输入事件。 ViewPostImeInputStage处理view控件的事件 frameworks/base/core/java/android/view/InputEventReceiver.java dispatchInputEvent frameworks/base/core/jav…