一、校验和是如何计算的?
这个问题牵扯到计算机最底层最神秘的部分——二进制运算。说实话,从学计组计统起,我就比较讨厌思考二进制的相关运算。但毕竟是学这个的,只好硬着头皮想了。
首先发送方校验和的计算过程:(不考虑UDP加上伪首部,只是探讨给定一个偶数字节的字节串,如何计算它的校验和)
校验和部分置0
以16bit(双字节)为单位,做原码二进制加法。
溢出部分放到低位再相加,直到没有溢出部分。
取反
上述高位溢出部分放到低位再相加,这种运算我们叫他循环移位加法。循环移位加法有两个性质,结合律和交换律。这里我们不做具体证明,只是说明我证明的切入点。规定循环移位加法的符号为。设两个16位二进制数分别为a和b。则
这样两条性质使得校验和起到校验作用,接收方只需要:
以16bit(双字节)为单位,做原码二进制加法。
溢出部分放到低位再相加,直到没有溢出部分。
检查结果是否为全1
二、为什么这么计算(循环移位和)?
上述是校验和的进本工作方式,但为什么要使用循环移位和的方式?如果只是做简单的原码加和,去掉溢出高位,再取反做校验和,是否也起到了校验的作用?确实能起到校验作用。但是学过计算机系统的同学应该知道,计算机有大端序和小端序,如果两个使用不同字节顺序的主机互发数据,那么由于字节顺序不同,校验和必然无法完成使命。这里引用一个例子:
对于一串16进制数据:0001f203f4f5f6f7

使用循环移位和,无论哪种字节顺序,最终结果都是相同的!网络科学家就是能带来这种小小的二进制震撼。
附 计算机网络考试中的一些小点
1.TCP报文中的ACK确认号是期望收到的下一个报文,滑动窗口协议中累计确认的ACK确认号是确认该号之前的数据帧已经收完,期望收到确认号加一数据帧。