在各种数据报的格式中,几乎都会有checksum的这一项校验和,我们知道他是用来检验数据报首部在传输过程中是否发生了差错用的。但是对于它是怎么具体计算的,在大二学完《计算机网络》还是没搞明白,今天在看Stevens 的《TCP/IP Illustrated 卷二》时看见了具体算法的描述,所以就学习了一下。
checksum 这个值是在IP首部的其他选项填写完毕后才进行计算的, 关于他的计算算法是这样描述的:
- 待校验的相邻字节成对组成16比特整数并计算其和的二进制反码。
- 为了生成校验和,校验和区域本身应当先置0,并和待校验数据相加,其和进行二进制反码运算后赋给校验和区域。
- 检查校验和时,将所有字节,包括校验和,进行相加并求二进制反码。如果结果为全1,则检查通过。
下面就拿IP数据报的首部作为一个例子,对于一个20字节的首部,我们分组取16bit的整数如下
45 00 00 28 29 57 40 00 32 06 00 00 41 37 c2 ac c0 a8 01 67
以上红字标注的是checksum在IP报头的位置,这个IP报头是我用抓包工具抓到的,为了体现怎么算出checksum,
所以将其去掉了现在万事俱备,开始计算他们的反码和(注意机器计算,使用循环进位):
4500+0028+2957+4000+3206+0000+4137+c2ac+c0a8+0167=a779
因此,和的反码就是58 86,这个16bit的值就是我们要填的checksum的值。
下面是检验接收方收到的IP首部应为
45 00 00 28 29 57 40 00 32 06 58 86 41 37 c2 ac c0 a8 01 67
同样也求反码和(仍为循环进位):
4500+0028+2957+4000+3206+5886+4137+c2ac+c0a8+0167=ffff
接收方验证结果全为1,说明首部传输没有错误。
如果结果不全为1,那么IP就丢弃收到的数据报,但不产生差错的报文,由上层去发现丢失的数据报并要求重传。
原文地址: http://blog.sina.com.cn/s/blog_85eb9f6501019x0w.html