理解UDP协议的首部校验和校验和

reference:

            https://blog.csdn.net/qiuchangyong/article/details/79945630

            https://seanwangjs.github.io/2017/10/19/udp-protocol-checksum.html

 

关于udp传输的不可靠性,用过这个的人都知道会丢包。具体细节可能就不清楚了,经过我的理解和总结,有以下两点:

1)udp包的大小可以达到64k,但实际上mtu大小只有1k多,如果直接发一个超过mtu大小的包,就会在协议层被分片,这样的问题是,如果只要有一个分片在传输中出错了即校验不正确(这是较容易发生的),整个传输的udp包就被丢弃。注意是整个而不是单个分片。这就是为什么发送udp包通常也是1k多大小的原因,rtp是在udp之上的协议,也考虑了这个问题。

2)实际上收到的数据都是经过校验的,不存在传错的问题,即在应用层调用udp传输时,不会出现发送了"ABCD",收到的却是"ABED"的情况,只有丢包或乱序的问题。而udp接收缓冲区过小也是造成丢包的原因,适当增大udp缓冲区能够降低丢包率。

在实际应用中,比如流媒体传输中,就要对接收的乱序的包进行重排(重排时间的长短又是一个关键),这时候发现某个包丢了(前提是要加一个序号,这个rtp包头里面有),还需要做重传的工作,然而udp协议就是为了传输的实时性而生的,所以这里面就有一个权衡的问题,既不能全部都重传,也不能不重传。如果全部都重传,那就和TCP没有区别了;如果不重传,丢包就会导致流媒体的不完整性,需要做的处理就是错误修复或隐藏,对于音频和视频都有一些算法,由于信息丢失,这些算法也只能做一些弥补,但对于无法进行重传的情况,比如播放基于udp的ts节目流,这些纠错算法的好坏就是关键。

 

45 00 00 2e----4表示ip版本号为ip第4版;5表示首部长度为5个32 bit字长,即为20字节;00 2e表示ip总长度为46字节,其中ip数据部分为26字节。 
be 55 00 00----be 55表示标识符;00 00表示3 bit标志及13 bit片偏移量; 
7a 11 51 ac----7a表示ttl值为122;11表示协议号为17的udp协议;51 ac表示16 bit首部检验和值; 
de b7 7e e3----表示32 bit 源ip地址为222.183.126.227 
c0 a8 12 7a----表示32 bit 目的ip地址为192.168.18.122

-------------------------------------------------------------------------------------------

检验和计算: 
首先,把检验和字段置为0。 
45 00 00 2e 
be 55 00 00 
7a 11 00 00<----检验和置为0 
de b7 7e e3 
c0 a8 12 7a 
其次,对整个首部中的每个16 bit进行二进制反码求和,求和值为0x3_ae50,然后3+ae50=0xae53(这是根据源代码中算法 cksum = (cksum >> 16) + (cksum & 0xffff) 进行的 ) 
最后,ae53+51ac=ffff。因此判断ip首部在传输过程中没有发生任何差错。

"二进制反码求和" 等价于 "二进制求和再取反"
从源代码看,很关键的一点是二进制求出的和如果大于16位时所做的操作,用和值中高16位加上低16位的值作为最终的和值,然后再做取反运算.


 

对于TCP和UDP的数据报,其头部也包含16位的校验和,校验算法与IPv4分组头完全一致,但参与校验的数据不同。这时校验和不仅包含整个TCP/UDP数据报,还覆盖了一个虚头部。虚头部的定义如下:

 

                     0         7 8   15 16   23 24       31 
                    +--------+--------+--------+------------+
                    |             source address              |
                       +--------+--------+--------+---------+
                    |           destination address          |
                    +--------+--------+--------+------------+
                    |  zero  |protocol| TCP/UDP length  |
                    +--------+--------+--------+------------+

其中有IP源地址,IP目的地址,协议号(TCP:6/UDP:17)及TCP或UDP数据报的总长度(头部+数据)。将虚头部加入校验的目的,是为了再次核对数据报是否到达正确的目的地,并防止IP欺骗攻击(spoofing)。

 

以及这段信息的十六进制表示

有了以上这些内容,剩下的就是对照着最开始的图表来寻找各个参数的值了( wireshark 一个十分好用的功能就是点选上面的人类可读内容,其十六进制值会在下面高亮显示)。我用下表来表示

keyhumanhex
Source192.168.1.106c0a8 016a
Destination11.111.111.1110b6f 6f6f
ProtocolUDP(17)11
Length1711
Source Port63549f83d
Destination Port123453039
Length1711
Checksum0xb12db12d
Datahello UDP6865 6c6c 6f20 5544 5000

然后就可以开始着手校验和的计算了,但在这之前还应注意,上表中有一项 Checksum ,这是发送方根据发送内容计算出来校验和,接受方需要根据收到的内容重新计算一遍校验和,然后再对比两者。所以在接收方计算时应该忽略这里 Checksum 项。

再次举例:

source ip

destination ip

protocol udp :固定为0x11

length*2 : length为:数据长度+8;

source port

destination port

data:从开头取16bit,当结尾为8bit,将低8bit设为0x00;当然0x00不能算为数据长度

上述计算完成后,将超过16bit的高位截取,加到低16bit中;再取反,即0xFFFF减去其即可。


C0A8_0003
C0A8_000A
11
10 (8+8)
10
8000
8000
1122_3344_5566_7788
----------------------
3_92E2
-------
92E5
------
6D1A

转载于:https://www.cnblogs.com/limanjihe/p/10177195.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值