TCP一定可靠吗

07-07 695阅读

背景

公司某个服务发送TCP报文后,得到的响应是非预期数据
原因竟然是:TCP包的 payload 数据某个bit位被翻转,但是 checksum 的值一样,错误的包被分发给了上层服务

Checksum介绍

IP 头有自己的 Checksum,TCP、UDP 也有自己的 Checksum,分别校验不同部分的数据
IP 头的 Checksum 用于校验 IP 头的数据是否正确
TCP 的 Checksum 用于校验 TCP 头、TCP 数据部分是否正确
UDP 的 Checksum 用于校验 UDP 头、UDP 数据是否正确

TCP的校验和(Checksum)是用于检测 TCP 数据包中的数据错误的重要机制
它在数据传输过程中强制执行了数据完整性检查,以确保数据在传输过程中没有被损坏
TCP 校验和是 TCP 头的一部分,它覆盖了 TCP 头和 TCP 数据,还涉及到 IP 头的部分内容

校验和计算原理

TCP校验和是通过一种特定的方法计算出来的,它包括以下几部分内容:

  1. 伪头部(Pseudo-Header)
  2. TCP头
  3. TCP数据

伪头部

伪头部并不是实际传输的数据的一部分,而是一种在计算校验和时,用来增强数据完整性的机制
伪头部包含了一些 IP 层的信息
伪头部总共 12 字节(源IP、目的IP、占位符、协议、TCP长度)
伪头部格式如下
±---------------------±---------------------±---------------------±---------------------+
| 源地址 (32位) | 目的地址 (32位) |
±---------------------±---------------------±---------------------±---------------------+
| 零 (8位) | 协议 (8位) | TCP长度 (16位) |
±---------------------±---------------------+

  • 源地址:发送方的IP地址
  • 目的地址:接收方的IP地址
  • 零:8位的0值
  • 协议:8位的值,6代表TCP协议
  • TCP长度:TCP头和TCP数据部分的总长度,以字节为单位

计算校验和

校验和是通过计算16位字的和,然后取其反码(二进制反码)得到
具体步骤如下:
1、 先将需要计算checksum数据中的checksum设为0
2、 计算checksum的数据按2byte划分开来,每2byte组成一个16bit的值,如果最后有单个byte的数据,补一个byte的0组成2byte
3、 将所有的16bit值累加到一个32bit的值中
4、 将32bit值的高16bit与低16bit相加到一个新的32bit值中,若新的32bit值大于0Xffff,再将新值的高16bit与低16bit相加
5、 将上一步计算所得的16bit值按位取反,即得到checksum值,存入数据的checksum字段即可

校验和字段

TCP头中的第17~18字节(从1开始)是校验和字段
TCP一定可靠吗

发送方在计算校验和时,这两个字节初始化为0 (注意,初始化为 0xFFFF 也出现过问题)
计算所得的校验和填充到这两个字节,接收方则通过相同的方式重新计算校验和,并与接收到的校验和进行比较以验证数据完整性
检验和,2B,检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部。

示例代码

static u16_t chksum(void *dataptr, u16_t len)
{
   
  u32_t acc;
  u16_t src;
  u8_t *octetptr;
  acc = 0;
  octetptr = (u8_t*)dataptr;
  while (len > 1) {
   
    src = (*octetptr)  0) {
   
    src = (*octetptr) 
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]