TCP头部

TCP头部字段详解

1. 源端口和目的端口(各16位)

  • 功能:标识发送和接收应用程序

  • 范围:0-65535(0-1023为知名端口)

  • 技术细节

    • 客户端通常使用临时端口(1024-65535)

    • 服务端使用固定端口(如HTTP=80, HTTPS=443)

    • 支持端口复用(SO_REUSEPORT选项)

// Linux内核端口选择算法 (net/ipv4/inet_connection_sock.c)
int inet_csk_get_port(struct sock *sk, unsigned short snum) {
    // ... 实现端口自动选择和冲突处理
}

2. 序列号(32位)

  • 功能:标识发送的数据字节流

  • 初始序列号(ISN):基于时钟的随机算法(RFC 6528)

    • 防止序列号预测攻击

    • 避免旧连接的报文干扰

  • 内核实现

    // Linux ISN生成算法 (net/ipv4/tcp_ipv4.c)
    u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
                       __be16 sport, __be16 dport) {
        // 使用SipHash加密算法生成
    }
  • 回绕处理:当序列号达到2^32-1时回绕到0

3. 确认号(32位)

  • 功能:期望收到的下一个字节的序列号

  • 累积确认机制:确认号N表示所有小于N的字节已收到

  • 选择性确认(SACK):通过TCP选项实现非连续确认

4. 数据偏移(4位)

  • 功能:指定TCP头部长度(以4字节为单位)

  • 计算:头部长度 = 数据偏移 × 4

  • 范围:5(最小20字节)到15(最大60字节)

5. 保留位(4位)

  • 必须置0,为未来协议扩展保留

  • 实际使用中可能被实验性协议使用(需IANA批准)

6. 控制标志(9位)

标志位名称功能应用场景
URG紧急指针指示紧急数据处理Telnet中断命令
ACK确认确认号字段有效所有数据传输
PSH推送要求立即交付数据实时交互应用
RST重置立即终止连接端口扫描防御
SYN同步建立连接同步序列号三次握手
FIN结束发送方完成数据发送四次挥手

标志组合示例

  • SYN+ACK:连接建立响应

  • FIN+ACK:正常连接终止

  • PSH+ACK:即时数据传输

7. 窗口大小(16位)

  • 功能:接收方通告的可用缓冲区大小

  • 流量控制机制:动态调整发送速率

  • 窗口缩放选项:通过选项扩展窗口大小(最高1GB)

    // Linux内核窗口缩放处理 (net/ipv4/tcp_input.c)
    void tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb) {
        // ... 处理窗口缩放选项
    }

  • 零窗口探测:当窗口为0时发送探测报文

8. 校验和(16位)


10. 选项字段(可变长度)

选项结构:
+--------+--------+--------+--------+
| Kind   | Length | Data...         |
+--------+--------+--------+--------+

核心选项详解:

  • 覆盖范围:TCP头部+数据+伪头部

  • 伪头部结构

    0      7 8     15 16    23 24    31
    +--------+--------+--------+--------+
    |          source address           |
    +--------+--------+--------+--------+
    |        destination address        |
    +--------+--------+--------+--------+
    |  zero  |  PTCL  |    TCP length   |
    +--------+--------+--------+--------+
  • 计算算法

    uint16_t tcp_checksum(const void *buff, size_t len, in_addr_t src_addr, in_addr_t dest_addr) {
        uint32_t sum = 0;
        const uint16_t *ptr = buff;
      
        // 伪头部计算
        struct pseudo_header psh = {src_addr, dest_addr, htons(IPPROTO_TCP), htons(len)};
        sum = calculate(&psh, sizeof(psh));
      
        // 数据计算
        while (len > 1) {
            sum += *ptr++;
            len -= 2;
        }
        if (len > 0) sum += (*ptr) & htons(0xFF00);
      
        // 折叠进位
        sum = (sum >> 16) + (sum & 0xFFFF);
        sum += (sum >> 16);
        return (uint16_t)(~sum);
    }

    9. 紧急指针(16位)

  • 功能:当URG=1时,指示紧急数据结束位置

  • 计算:紧急数据结束 = 序列号 + 紧急指针

  • 实际应用:SSH/Telnet的中断命令(Ctrl+C)

Kind名称长度功能
0选项结束1选项列表结束
1无操作1选项填充
2最大报文段4协商MSS(通常1460)
3窗口扩大因子3窗口缩放(2^14倍)
4选择性确认2启用SACK功能
5SACK块可变非连续接收的数据块
8时间戳10RTT测量和PAWS保护
28用户超时4连接超时设置
29认证可变TCP-AO安全认证

超时重传为例,假设客户端(Client)向服务器(Server)发送数据包,但未收到ACK确认。

    场景步骤:

    Client发送数据包(初始传输)

    • TCP头部包含选项字段(如时间戳):
      数据偏移 = 8(头部总长32字节 = 8 × 4)
      选项字段:时间戳(Timestamp)值 = T1
      序列号(Seq) = 100
      数据 = "Hello"
      
    • 数据包结构:
      | 20字节固定头部 | 12字节选项(时间戳) | 数据 "Hello" |
      

    Server未收到该包(可能因网络拥塞丢失):

    • Client在重传超时(RTO) 后未收到ACK,触发重传。

    Client重传数据包

    数据偏移 = 8(长度不变)
    选项字段:时间戳值 = T2(T2 > T1)
    序列号(Seq)仍为 100(相同数据)
    数据 = "Hello"(不变)
    

    关键点分析:

    • 选项长度一致性:重传时数据偏移值仍为8,表明头部长度未变(选项字段仍存在)。
    • 选项内容变化:时间戳更新(T1 → T2),帮助计算RTT(往返时间)和重传延迟。
    • 接收方处理:Server通过数据偏移=8跳过32字节头部,直接解析数据"Hello"。
    ### TCP头部结构及字段详解 TCP(Transmission Control Protocol)头部结构是TCP协议中非常重要的部分,用于确保数据传输的可靠性和准确性。以下是TCP头部的主要字段及其功能: #### 1. 源端口号 (Source Port) - 占用2字节。 - 标识发送方的应用程序端口,以便接收方能够将数据正确地返回给相应的应用程序[^1]。 #### 2. 目的端口号 (Destination Port) - 占用2字节。 - 标识接收方的应用程序端口,确保数据被传递到正确的服务或应用[^1]。 #### 3. 序列号 (Sequence Number) - 占用4字节。 - 表示本报文段所发送的数据的第一个字节的序列号。通过序列号机制,TCP可以实现数据的有序传输和丢失重传[^1]。 #### 4. 确认号 (Acknowledgment Number) - 占用4字节。 - 表示期望收到的下一个报文段的第一个字节的序列号。只有当ACK标志位为1时,确认号字段才有效[^1]。 #### 5. 数据偏移 (Data Offset) - 占用4位。 - 表示TCP头部的长度,以4字节为单位。由于TCP头部可能包含选项字段,因此需要明确头部的实际长度[^1]。 #### 6. 标志位 (Flags) - 占用6位,包括以下字段: - URG:紧急指针是否有效。 - ACK:确认号是否有效。 - PSH:是否要求立即交付数据。 - RST:复位连接。 - SYN:同步序列号,用于建立连接。 - FIN:结束连接[^1]。 #### 7. 窗口大小 (Window Size) - 占用2字节。 - 表示当前允许发送方发送的数据量,用于流量控制[^1]。 #### 8. 校验和 (Checksum) - 占用2字节。 - 用于检测TCP头部和数据部分的错误,确保数据传输的完整性[^1]。 #### 9. 紧急指针 (Urgent Pointer) - 占用2字节。 - 只有当URG标志位为1时,该字段才有效。它指出本报文段中的紧急数据相对于序列号的偏移值[^1]。 #### 10. 选项 (Options) - 长度可变,最大为40字节。 - 包含一些额外的信息,例如窗口缩放、时间戳等。每个选项由kind、length和info三个字段组成[^2]。 #### 示例代码 以下是一个简单的Python代码,用于解析TCP头部的部分字段: ```python import struct def parse_tcp_header(data): tcp_header = data[:20] unpacked_data = struct.unpack('!HHLLBBHHH', tcp_header) source_port = unpacked_data[0] destination_port = unpacked_data[1] sequence_number = unpacked_data[2] acknowledgment_number = unpacked_data[3] data_offset = unpacked_data[4] >> 4 flags = unpacked_data[5] window_size = unpacked_data[6] checksum = unpacked_data[7] urgent_pointer = unpacked_data[8] return { 'source_port': source_port, 'destination_port': destination_port, 'sequence_number': sequence_number, 'acknowledgment_number': acknowledgment_number, 'data_offset': data_offset, 'flags': flags, 'window_size': window_size, 'checksum': checksum, 'urgent_pointer': urgent_pointer } # 示例数据 data = b'\x00\x35\x00\x50\x00\x00\x00\x01\x00\x00\x00\x00\x80\x10\x12\x34\x00\x00\x00\x00' parsed_data = parse_tcp_header(data) print(parsed_data) ```
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值