传输协议的可靠性
- TCP协议(Transmission Control Protocol,传输控制协议)为应用层提供可靠的、面向连接的和基于流(stream)的服务。使用超时重传、数据确认等方式来确保数据包被正确发送至目的地。
- UDP(User Datagram Protocol,户数据报协议)是无连接的,面向消息的数据传输协议,与TCP相比,有两个致命的缺点:
(1)数据包容易丢失;
(2)数据包无序。
UDP是传输层的协议,不可靠,如果物理层,数据链路层或网络层能提供可靠性的话,那么UDP就可以利用下面各层的可靠性实现自己的可靠性;然而,UDP是不可靠的,也就是说它下面的各层并不能保证UDP可靠性,所以只能靠上面的应用层来保证可靠性。所以必须制定上层的协议,包括:流控机制、超时机制、重排机制、重传机制。
可靠UDP适用场景 问题来了,既然想要使用可靠的UDP,那就必须补充一些TCP的流控机制、超时机制、重排机制、重传机制,那么这和TCP有什么区别,为何不直接使用TCP更省事呢?
- 网速的提升给UDP稳定性提供可靠网络保障。CDN服务商Akamai(NASDAQ: AKAM)报告从2008年到2015年7年时间,各个国家网络平均速率由1.5Mbps提升为5.1Mbps,网速提升近4倍。网络环境变好,网络传输的延迟、稳定性也随之改善,UDP的丢包率低于5%,如果再使用应用层重传,能够完全确保传输的可靠性。
- 对比测试结果UDP性能优于TCP。为了提升浏览速度,Google基于TCP提出了SPDY协议以及HTTP/2。Google在Chrome上实验基于UDP的QUIC协议,传输速率减少到100ms以内。
Google搜索采用QUIC后页面加载性能提升3%。
YouTube采用QUIC后重新缓冲次数减少了30%。
文章图片
- TCP设计过于冗余,速度难以进一步提升。TCP提供了过多的保护,在及时性上做了很多的妥协,比如:控制微包(Nagle算法),延时ACK,流量控制,超时重传等,这些设计严重影响了Tcp的速度和及时性。由于TCP内置在系统协议栈中,极难对其进行改进。
- 寄希望于业务逻辑上允许信息丢失。UDP它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。需要对 UDP 的不可靠传输进行适当的改进,以减少数据的丢失。应用进程可以在不影响应用的实时性的前提下,增加一些提高可靠性的措施,如采用前向纠错或重传已丢失的报文
- TCP 是个基于公平性的可靠通信协议,但是在一些苛刻的网络条件下 TCP 要么不能提供正常的通信质量保证,要么成本过高。为什么要在 UDP 之上做可靠保证,究其原因就是在保证通信的时延和质量的条件下尽量降低成本。
- TCP是强制的可靠性传输,其在IP协议的基础上,发送端对所有的数据进行定时重传,接受端对所有的数据进行排序,以此(当然还有很多其他的机制)来实现发送端是什么样子的,接受端就能接受到什么样子的数据。但是现实中有一些场景,我们并不需要如此固执的可靠性。
- 当服务器设计容量是海量级的应用,一台服务器要同时容纳十几万的并发连接,因此服务器端只有采用UDP协议与客户端进行通讯才能保证这种超大规模的服务。比如QQ,如果用tcp的话,服务端会接受海量连接,每个连接要维持一个连接,占用很多资源,tcp的包和udp的包没有任何不同,只不过tcp的可靠性由操作系统保证,udp可靠性由腾讯程序员保证,qq聊天只是字符,数据量很小,所以不用tcp的复杂流量控制。
采用UDP有3个关键点:
- 网络带宽需求较小,而实时性要求高;
- 大部分应用无需维持连接;
- 需要低功耗。
UDP分片原理 1.对应用层的数据进行分片,以满足MTU传输的要求
2.在发送端给分片编号,在接收端重组分片,解决乱序数据包重组的问题
UDP传输应用层需注意的问题
1.数据包确认机制,可以对数据报进行确认和排序
2.数据包重发机制,能避免数据报丢失
3.尽量不发送大于路径MTU的数据包
4.处理数据包重排
所以,总的来看,就是需要在应用层实现一个简单版的TCP,是不是觉得很好笑,放着好好的轮子不用,非要自己造一个。
UDP和MTU的关系
- MTU,最大传输单元(Maximum Transmission Unit)是指通信协议的某一层上面所能通过的最大数据包大小(以字节为单位),最大为1500字节(局域网发送)。
- 单个UDP传输的最大内容1472(1500-20-8)字节,但由于不同的网络中转设备设置的MTU值并不相同。Internet上的标准MTU值为576字节(公网),建议在进行Internet的UDP编程时,最好将UDP的数据长度控制在548字节(576-20-8)以内。
文章图片
UDP分片设计
文章图片
文章图片
大数据,分块传输,接收后通过附加信息组合。
文章图片
如何提高UDP的可靠性 本端:首先在UDP数据报定义一个首部,首部包含确认序列号和时间戳,时间戳是用来计算RTT(数据报传输的往返时间),从何计算出合适的RTO(重传的超时时间)。然后以等-停的方式发送数据报,即收到对端的确认之后才发送下一个的数据报。当时间超时,本端重传数据报,同时RTO扩大为原来的两倍,重新开始计时。
对端:接受到一个数据报之后取下该数据报首部的时间戳和确认序列号,并添加本端的确认数据报首部之后发送给对端。根据此序列号对已收到的数据报进行排序并丢弃重复的数据报。
UDP分片的代码实现 还在开发中,待完善
巨人的肩膀
从他人的工作中汲取经验来避免自己的错误重复,正如我们是站在巨人的肩膀上才能做出更好的成绩。【可靠UDP浅入】https://segmentfault.com/a/1190000018902719
https://www.cnblogs.com/zhangbing12304/p/11016921.html
https://blog.csdn.net/bobozai86/article/details/87518617
https://www.cnblogs.com/home123/p/7499608.html
https://www.cnblogs.com/lixiang-share/p/7152870.html
https://blog.csdn.net/pangyemeng/article/details/50387078
https://www.jianshu.com/p/4d12ad2e7500
https://mp.weixin.qq.com/s/fZ_QeTsS7kbZnfUL-A3UUA
推荐阅读
- 计算机网络|计算机网络——DHCP协议详解
- Linux|Linux--网络基础
- 网络|一文彻底搞懂前端监控
- 网络夺命连环问系列|网络夺命连环问5--HTTP怎么传输大文件()
- 网络|网络编程释疑(TCP连接拔掉网线后会发生什么)
- 网络|简单聊聊压缩网络
- Java|图解四大IO模型与原理
- 卷积|吃透空洞卷积(Dilated Convolutions)
- 计算机网络|网桥与交换机
- Karpenter : 新一代 Kubernetes auto scaling 工具