1. TCP校验和

add: 2021-08-09

1.1. 检验和目的

目的是为了发现TCP首部和数据在发送端到接收端之间发生的任何改动。如果接收方检测到检验和有差错,则TCP段会被直接丢弃。

TCP在计算检验和时,要加上一个12字节的伪首部。

1.2. 伪首部

伪首部

伪首部共有12字节,包含IP首部的一些字段,有如下信息:32位源IP地址、32位目的IP地址、8位保留字节(置0)、8位传输层协议号(TCP是6,UDP是17)、16位TCP报文长度(TCP首部+数据)。

伪首部是为了增加TCP校验和的检错能力:通过伪首部的目的IP地址来检查TCP报文是否收错了、通过伪首部的传输层协议号来检查传输层协议是否选对了。

1.3. 检验和计算过程

TCP首部校验和计算三部分:TCP首部+TCP数据+TCP伪首部

  • 发送端:
    • 首先,把伪首部、TCP报头、TCP数据分为16位的字,如果总长度为奇数个字节,则在最后增添一个位都为0的字节。
    • 把TCP报头中的校验和字段置为0。
    • 其次,用反码相加法(对每16bit进行二进制反码求和)累加所有的16位字(进位也要累加,进位则将高位叠加到低位)。
    • 最后,将上述结果作为TCP的校验和,存在检验和字段中。
  • 接收端:
    • 将所有原码相加,高位叠加到低位, 如计算结果的16位中每一位都为1,则正确,否则说明发生错误。

1.3.1. 简单理解校验和计算过程

  • 发送方:
    • 将校验和字段置为0,然后将IP包头按16比特分成多个单元,如包头长度不是16比特的倍数,则用0比特填充到16比特的倍数;
    • 对各个单元采用反码加法运算(即高位溢出位会加到低位,通常的补码运算是直接丢掉溢出的高位),将得到的和的反码填入校验和字段;
    • 发送数据包。
  • 接收方:
    • 将IP包头按16比特分成多个单元,如包头长度不是16比特的倍数,则用0比特填充到16比特的倍数;
    • 对各个单元采用反码加法运算,检查得到的和是否符合是全1(有的实现可能对得到的和会取反码,然后判断最终值是不是全0);
    • 如果是全1则进行下步处理,否则意味着包已变化从而丢弃之。需要强调的是反码和是采用高位溢出加到低位的,如3比特的反码和运算:100b+101b=010b(因为100b+101b=1001b,高位溢出1,其应该加到低位,即001b+1b(高位溢出位)=010b)。

1.4. 验证示例:

校验和 反码求和过程

以4bit 为例

  • 发送端计算:

    • 数据: 1000 0100 校验和 0000
    • 则反码:0111 1011 1111
    • 叠加: 0111+1011+1111 = 0010 0001 高于4bit的, 叠加到低4位 0001 + 0010 = 0011 即为校验和
  • 接收端计算:

    • 数据: 1000 0100 检验和 0011
    • 反码: 0111 1011 1100
    • 叠加: 0111 + 1011 +1100 = 0001 1110 叠加为4bit为1111. 全为1,则正确

1.5. UDP检验和

基本过程和TCP检验和相同,不同的是UDP的伪首部中8位传输层协议号是17而TCP是6。如下图所示

伪首部

1.6. IP检验和

IP首部中的检验和只覆盖IP的首部,不覆盖IP数据报中的任何数据

1.7. 三者检验和的异同

  • TCP和UDP检验和是一个端到端的检验和,由发送端计算,然后由接收端验证。

  • TCP和UDP检验和覆盖首部和数据,而IP首部中的检验和只覆盖IP的首部,不覆盖IP数据报中的任何数据。

  • TCP的检验和是必需的,而UDP的检验和是可选的。

  • TCP和UDP计算检验和时,都要加上一个12字节的伪首部。

本文摘自: TCP检验和

results matching ""

    No results matching ""