UDP校验和(UDP checksum)是一种用于检测传输中的UDP数据包在传输过程中是否发生错误的机制。UDP(用户数据报协议)是一种简单的无连接的传输层协议,它用于在网络中发送数据包,但不提供数据包的传输可靠性或顺序保证。
在UDP数据包中,校验和字段用于检测数据包在传输过程中是否发生了改变,比如由于网络噪声、硬件故障或其他原因导致的数据损坏。校验和的计算方法如下:
-
将UDP头部和数据部分的所有16位字(2个字节)相加,如果数据长度不是偶数,会在末尾添加一个字节的填充(值为0)以确保是16位字。
-
如果相加的过程中出现溢出(即超过16位),则将溢出的部分加到结果的低16位上。
-
将最终的结果取反(按位取反)得到校验和。
在接收端,对整个UDP数据包(包括校验和字段)进行同样的计算,如果结果为全1(即0xFFFF),则认为数据包没有错误。如果计算结果不是全1,则表明数据包在传输过程中可能发生了错误,接收端通常会丢弃这个数据包。
值得注意的是,UDP校验和是可选的,在IPv4中可以将校验和字段设置为0来禁用校验和检查,但在IPv6中,UDP校验和是必须的。
让我们通过一个简单的例子来说明UDP校验和的计算方法。假设我们有一个简单的UDP数据包,它的头部和数据如下(以16位字表示):
cpp
头部:
- 源端口号:1010(十六进制)
- 目的端口号:2020(十六进制)
- 长度:0014(十六进制,表示20字节,包括头部和数据)
- 校验和:0000(十六进制,暂时假设为0,稍后计算)
数据:
- 数据1:1234(十六进制)
- 数据2:5678(十六进制)
- 数据3:9ABC(十六进制)
校验和的计算过程如下:
-
将所有16位字相加:
- 1010 + 2020 + 0014 + 0000 + 1234 + 5678 + 9ABC = 133AC(十六进制)
-
处理溢出:
- 133AC(十六进制)= 1 + 33AC(十六进制)= 33AD(十六进制)
-
取反:
- 校验和 = ~33AD(十六进制)= CC52(十六进制)
因此,计算得到的UDP校验和为CC52(十六进制)。在实际的UDP数据包中,这个校验和值会被放在头部的校验和字段中。
在接收端,接收方会对包括校验和在内的整个数据包进行相同的计算。如果结果为全1(即FFFF十六进制),则认为数据包没有错误。如果结果不是全1,则表明数据包在传输过程中可能发生了错误,接收端通常会丢弃这个数据包。
如果接收端收到的数据包没有错误,那么我们可以使用与之前相同的数据,但这次我们将使用计算出的校验和CC52(十六进制)替换校验和字段:
cpp
头部:
- 源端口号:1010(十六进制)
- 目的端口号:2020(十六进制)
- 长度:0014(十六进制,表示20字节,包括头部和数据)
- 校验和:CC52(十六进制)
数据:
- 数据1:1234(十六进制)
- 数据2:5678(十六进制)
- 数据3:9ABC(十六进制)
接收端将对包括校验和在内的整个数据包进行相同的计算:
-
将所有16位字相加:
- 1010 + 2020 + 0014 + CC52 + 1234 + 5678 + 9ABC = 1FFFE(十六进制)
-
处理溢出:
- 1FFFE(十六进制)= 1 + FFFE(十六进制)= FFFF(十六进制)
这一步叫做回卷加法,一直进行直到不产生溢出为止。
- 1FFFE(十六进制)= 1 + FFFE(十六进制)= FFFF(十六进制)
接收端计算的结果是全1(FFFF十六进制),这意味着数据包没有错误。因此,接收端可以接受这个数据包并继续处理数据。如果计算结果不是全1,则表明数据包在传输过程中可能发生了错误,接收端通常会丢弃这个数据包。
《计算机网络:自顶向下方法》的配套课件中,关于UDP校验和描述如上图所示。
这些PPT解释了UDP校验和的工作原理和它在错误检测方面的局限性。
第一张图展示了一个UDP校验和的简化例子。在传输过程中,发送方发送了两个数字:5和6,它们的和是11。然而,由于某种错误,接收方收到了数字4和6,其和仍然是11。接收方计算得到的校验和与发送方的不一致,因此它能够检测到错误。
第二张图讲述的是UDP校验和的目标,它是为了检测传输段中的错误(如位翻转)。发送方处理UDP段的内容(包括UDP头部和IP地址)作为16位整数数组,并对这些整数数组的内容进行加法运算得到校验和,然后将校验和的值放入UDP校验和字段中。接收方计算接收到的段的校验和,如果计算出的校验和与校验和字段中的值不相等,则检测到错误;如果相等,则认为没有检测到错误。但是,这种方法并不百分百可靠,稍后会有更多的解释。
第三张图提供了一个具体的计算例子,显示了两个16位整数相加的情况。当两个数字相加时,最高位的进位需要被回绕到结果中。在图中,两个数相加后产生了一个进位,这个进位被加回到了结果的最低位。然后,为了得到校验和,这个总和将会被取反。
第四张图揭示了UDP校验和机制的一个弱点。它展示了即使在两个数中有一位发生了变化(位翻转),这个变化可能不会影响最终的校验和。这是因为变化的两位相互抵消了。这个例子说明UDP校验和无法检测到所有的错误,尤其是当多个错误相互抵消时。这种情况显示了UDP校验和提供的错误检测保护是有限的。