校验TCP和UDP的校验和

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了校验TCP和UDP的校验和相关的知识,希望对你有一定的参考价值。

 

  一开始,私以为校验和只是简单的求和得到的结果,后来在TCP和UDP里面看到使用的校验和方式有点奇怪--二进制反码(循环进位)求和

  人类的认知过程必将从简单到复杂,看下这个二进制反码循环求和是啥子意思。以16进制示例:

  1.对校验序列word1,word2...wordn的二进制表示求反码

  2.对求的反码序列循环进位求和,循环进位求和的意思是指把求和的进位加到低位,可能进位有x位,把这x位表示的数字和求和结果的16位相加。

  感觉好像变复杂了。没关系,二进制反码循环进位求和有以下特性:

  1.求和过程先求反码再二进制循环进位求和等价于先二进制循环进位求和再对求和结果求反码。(如此大大减少求反码的次数)

  2.与字节序(大端小端问题)无关。(这也许是许多协议使用这种方式求和的原因)

 1 ///@func:To caculate the Checksum of data
 2 ///@param:    1.nums :the number of sizeof(unsigned short int)
 3 ///
 4 unsigned short int WordCheckSum(const unsigned short int *data, unsigned short int nums)
 5 {
 6     short int index = 0;
 7     unsigned int sum = 0;
 8     unsigned short int checkSum ;
 9     for (index = 0; index < nums;index++)
10     {
11         sum += data[index];
12     }
13     //cout << "the sum of data is: " << hex << sum << endl;
14     checkSum = (unsigned short int)(sum & 0xffff)+(unsigned short int)(sum >> 16) ;
15     /*cout << "the checkSum of data is: " << checkSum << endl;*/
16     return ~checkSum;
17 }

  测试代码:

WORD data1[5] = {
        0x1122, 0x1122, 0x1122, 0x1122, 0x1122
    };
    WORD data2[5] = {
        0x2211, 0x2211, 0x2211, 0x2211, 0x2211
    };
    cout << "the CheckSum of data1 is: " << hex << WordCheckSum(data1, 5) << endl;
    cout << "the CheckSum of data2 is: " << hex << WordCheckSum(data2, 5) << endl;

  测试结果:

技术分享

  可见,二进制反码求和与字节序无关。

以上是关于校验TCP和UDP的校验和的主要内容,如果未能解决你的问题,请参考以下文章

UDP协议:UDP和TCP相比快在哪里?

校验和计算方法

什么是校验和?

TCP和UDP的区别及应用场景

UDP 数据是不是会损坏?

协议分析:IP校检和算法