tcp udp 的粘包 断包分析

此篇分析来来自于一次面试经历,面试官问对于断包问题tcp跟udp分别的处理方式?然后我就在这里总结下粘包断包问题。

一,从TCP与UDP的区别讲起

网络数据经过路由器,如果数据很小,没有超过路由器的封包大小,就会直接直接经过路由器到达下一个路由器,一层一层最终到达目的地
如果数据很大,这里指一个发送,超过了路由器的封包大小,那么路由器就会把这个数据包进行拆分,比如拆分成A B C三个包,这三个包都没有超过路由器的封包大小,到达下一个路由器的时候,TCP与UDP的区别就来了:
TCP收到A的时候,会resp通知源路由器,A到达,B C包依然如此,如果由于网络的各种原因,目的路由收到了A C,B没有收到,TCP会要求源路由把B包重新发一次,直到ABC包目的路由都接受到了,那么目的路由把ABC包重新组成起始包,继续往下一个路由发送,这就是TCP安全连接的由来,只要发送,我就能保证目的一定能收到(网络断开能检测到)
UDP则不是这样,如果ABC包拆分之后,目的路由只收到AC,经过检测,B没有被收到,那么此包就会被当作不完整,直接被丢弃。由于UDP没有resp的通知过程,所以,UDP的传输效率要高一些,当然安全性也低一些

 

由上面的这些可以得出结论:UDP是绝对不会被粘包,因为路由器收到的只会是完整数据才会继续下发,什么粘包处理完全没有必要。

 

 

二,UDP,保护消息边界和流

保护消息边界,就是指传输协议把数据当作一条独立的消息在网上传输,接收端只能接收独立的消息。也就是说存在保护消息边界,接收端一次只能接收发送端发出的一个数据包。而面向流则是指无保护消息保护边界的,如果发送端连续发送数据,接收端有可能在一次接收动作中,会接收两个或者更多的数据包。
例如,我们连续发送三个数据包,大小分别是2k,4k ,8k,这三个数据包,都已经到达了接收端的网络堆栈中,如果使用UDP协议,不管我们使用多大的接收缓冲区去接收数据,我们必须有三次接收动作,才能够把所有的数据包接收完.而使用TCP协议,我们只要把接收的缓冲区大小设置在14k以上,我们就能够一次把所有的数据包接收下来,只需要有一次接收动作。

粘包,拆包是针对tcp协议的。

三,粘包、拆包发生原因
发生TCP粘包或拆包有很多原因,现列出常见的几点,可能不全面
1、要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包。
2、待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。
3、要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包。
4、接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。

四,粘包、拆包解决办法
推荐下面两种解决方法:
1、发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了。
2、可以在数据包之间设置边界,如添加特殊符号,这样,接收端通过这个边界就可以将不同的数据包拆分开。

 

 

 

你可能感兴趣的:(tcp udp 的粘包 断包分析)