UDP协议新认知

应用场景

在传输层上,进程每个操作,都会产生一个udp数据报,这个不同于tcp协议,tcp会对数据进行分段,成为一个个tcp报文段,再传输给网络层,每个tcp报文的可靠性通过tcp层来保证。但是udp并没有提供如此多的可靠性,从其首部8个字节,于tcp首部20个字节相比,就显得功能弱了很多。但是这并不是说udp就比tcp差,有时候应用场景上,还真得用udp,而不适合可靠性强的tcp,比如音视频,数据传输基本通过udp,因为在线视频,丢失了几个包,可能用户肉眼看不出区别,丢失大的时候,最多就卡顿一下。但是如果是保证可靠性、有序性的tcp协议,当数据包中间丢失了几个,导致整个数据流都不能使用(一直在使用超时重传的步骤),这可能就是致命的。还有qq的文件传输,以及现在一些开源的im通信框架,都是投向udp的怀抱。一般在操作系统上,tcp和udp提供是两种服务,但是经常会使用同一个端口号,这不是两个协议规定的,而是作为用户的我们,在使用习惯和方便的角度上去考虑的。

首部校验和

udp和tcp的检验和,取用的数据是数据内容+头部进行计算,这样可以保证我们的数据可以不被篡改。而ip的首部校验和一般就只有ip的首部进行计算,因为内容已经通过传输层计算过了,保证过了,这里ip只要保证其目标ip,源ip等信息正确就可以了。

IP分片

上面说到,进程每个操作产生一个udp数据报,如果这个操作数据量非常大,按照tcp/ip协议的模型,往网络层再加上ip首部,往链路层再封装成数据帧,那么好像最后分组的长度非常大,但是我们知道在网络传输链路上,有一个叫MTU的东西,保证端到端之间,最大的传输单元,所以对于没法自己切割数据报的udp,在网络层,就需要进行切割了,而这个切割,就成为ip分片。基本流程是:
首先udp产生了非常大的数据报,传输到网络层,网络层通过下面的接口层,查看待发送接口的MTU大小,如果此时的ip数据报大于MTU,那么就要进行数据分片了。接着假设需要分片成两份,将源数据报进行首部进行复制,然后“塞满”整个数据区域,记录数据字节大小,已经标记未完的“+”标识。下一个分片中,就要需要记录数据的偏移量(头一个的偏移量也要记录,当时在上一个,就是0),数据字节大小,没有标识。这样在接收的时候,根据有没有“+”就知道数据是否已经完成了。
注意,ip分片的“分”的过程,不仅仅是源数据端,还有中间路由器也有可能分片,但是分片的“合”,就是目的主机上了。为什么中间路由也要分片?假设A发送数据给D,但是要经过路由器B和路由器C,A与B之间的MTU相对较大,所以不需要分片或者分片成较大数据报,但是B和C的MTU比较小,那么数据报经过B后,就要将分片大于MTU的数据报再进行分片。一般以太网上最大数据帧长度是1500B,而1500B还有包括20字节的ip首部和8字节的udp首部,那么数据区域长度就是1472B了(如果是tcp,因为tcp首部长度比较长,最大数据区域剩下1460)。
ip分片有个很大很严重的问题,就是如果在中间路由进行分片,对源主机是透明的,如果发生丢包,源主机是无法判断丢失了哪一个包,所以只能,把这段数据再发一次。。。。这看起来很糟糕,但是因为不像tcp那样,可以可靠控制数据报文段,所以tcp一般是不会让其发生ip分片的,这个在udp上,也尽量少用。

icmp不可达差错

上文说到了ip分片的不合理性,所以有时候会通过数据包进行标记(DF),标识这个数据报不进行分片。这个似乎有点流氓,分片与否好像不是你能决定的,所以带着DF标记的数据报,在小的MTU链路上,还是要进行分片,所以卡在的那个路由器上,就会返回ICMO不可达差错,怂了,还是要进行分片。

猜你喜欢

转载自blog.csdn.net/jerryJavaCoding/article/details/78370731