可靠UDP

tcp为我们做了什么事情?

总得来说,tcp做了这几件事:

  1. 通过序列号和基于确认的超时重传机制,为上层提供了可靠的字节流服务;
  2. 通过滑动窗口、拥塞窗口提供了流量控制;
  3. 默认情况下,为了有效利用带宽,tcp的报文一次会尽量携带更多的数据。但与此同时,为了避免IP层的分片,又不会发送超过MTU大小的数据包。

udp为我们做了什么事情?

首先应该清楚的是,一个udp数据包仅仅是在IP数据包之上加了一个udp协议头。这个协议头十分精简,仅有的四个字段是:目的端口号、源端口号、数据包长度、校验和。通过sendto这个syscall发送一个udp数据包时,实际上就是包装成一个IP数据包然后直接发送出去。这里并不会像tcp那样在本地缓存数据,直到达到一个长度限制后再发送出去。另外由于有检验和,所以我们不需要在udp之上再做校验的事情了。

一个可靠的udp协议

在清楚tcp做了什么事后,我们就有了实现一个可靠udp的思路了。首先需要说明的是,在udp之上实现一个tcp是没有意义的。实现一个可靠的udp协议往往是,根据业务需要,牺牲掉一部分的tcp的功能,来换取更高的性能。但是,在动手造轮子之前,我们应该分清的是,哪些功能是tcp已经为我们实现了的,而哪些功能是要通过自己定制一个可靠udp来实现的。比如说,上述的第3条,这个特性有时候会造成tcp的延迟性,但是通常可以通过设置TCP_NODELAY来解决。

实现一个最基础的可靠udp通讯协议,我们只需要提供一个重传机制即可。在这我实现了一个简单的可靠udp协议,这个协议为每一个发送出去的udp数据包分配一个包id,每次接收方收到一个数据包时,都要回应发送方一个ack对应这个包id。协议通过这种确认机制来保证接收方能收到发送方发出的udp数据包,在发出的时候,发送方应该设置一个计时器,超时的话会重传数据包。

这个协议做的就是这么多,它仅能确保接收方能收到发送方的udp包,并没有做其它的事情。

具体来说它没做这些事情:

  1. 它没有保证包的有序性。发送方连续发送几个udp数据包,接收方可以以任何顺序收到这几个数据包。如果想要做到有序性,必须由应用层来完成。
  2. 它没做流量控制。发送方连续大量发送数据包会导致网络性能变差,丢包次数增大。
  3. 它没对数据包大小做控制。为了避免IP层对数据包进行分片,应用层应该要保证每个数据包的大小不超过MTU。如果这个数据包会经过广域网(一般情况下)这个值应该不超过576。考虑到IP头的20字节,udp头的8个字节,以及这个协议头的字节。最好每次发送的数据大小在512以内。

这个协议这么简陋,那要它何用?

首先,对于互相独立的数据包,没有必要保证包的有序性。以游戏开发为例子,玩家在客户端发起一个开宝箱请求的同时,又迅速的切换界面,打开了角色面板又发起一个查看角色数据的请求。保证这两个请求的先后顺序真的有意义吗?

其次,对于大部分的小数据包,没有必要考虑IP分片。玩家发起一个开宝箱的请求,可能整个数据包的内容就是一个请求id和一个宝箱id。假设这两个id都是64位,也就是16字节,整个IP包的大小并不足以让IP层进行分片处理。如果你的系统绝大部分都是这种小包,或许你能不考虑IP分片。

再来谈谈tcp的字节流服务。正如大家所知道的,tcp是提供可靠的字节流服务的。但是,一般情况下我们真的需要传输层提供这种服务吗?以游戏服务器为例子,在用tcp与客户端进行网络通讯上,我们现在的做法是在字节流上对请求、响应进行封包解包,也就是在字节流之上,模拟一个数据包的传输。并且我相信很多其它游戏也是这么做的。数据在IP层上本来就是通过包的形式进行传输,tcp对此做了抽象实现了字节流,应用层又在字节流之上模拟出数据包。是否可以用udp去减少这些不必要的抽象呢?或许我们仅需要的是一个有序可靠的数据包服务,又或许我们连有序性都不需要。。。

总结

最后,我想说的是并没有一套解决方案能适用与所有情况。tcp作为传输层给出的是一套通用性的解决方案,并致力于满足大多数的需求,但是总会有其不适合的地方。这个时候我们就可以使用udp来自己定制一套时候自己业务的协议。这套协议不一定是很复杂,其实实现一个可靠的udp也并不是很复杂,关键要看你需要协议提供什么功能!

参考资料 

  1. 可靠UDP传输。地址:http://blog.codingnow.com/2016/03/reliable_udp.html
  2. KCP。地址:https://github.com/skywind3000/kcp
时间: 2024-10-08 12:43:16

可靠UDP的相关文章

可靠UDP设计

最近加入了一个用帧同步的项目,帧同步方案对网络有着极大的影响,于是采用了RUDP(可靠UDP),那么为什么要摒弃TCP,而费尽心思去采用UDP呢?要搞明白这个问题,首先要了解TCP和UDP的区别 , 明白TCP无法避免的痛点. TCP VS UDP 1.Tcp 面向连接,提供可靠的传输: UDP面向无连接,提供不可靠传输 2. Tcp 提供流量控制 : UDP不提供流量控制 3. Tcp 保证传输数据顺序 : UDP不保证传输顺序,也就是可能是乱序收包 4. TCP 面向字节流 : UDP 面向

Tcp可靠Udp不可靠原理

1. Socket缓冲区 应用程序通过调用send, read方法向网络上发送应用数据,该过程中由于应用程序调用send/write的速度同网络介质发送数据的速度存在差异,所以,应用通过socket发往 网络上的的数据会先被缓存,即socket发送缓冲区,等待网络空闲时再发送出去.同样,socket从网络上接受到的数据,也会被缓存,即socket接受缓冲区,等待应用程序把数 据从中读出.其中,应用程序调用send发送数据,是将数据拷贝到socket的内核发送缓冲区中,然后send便会返回,即se

高性能服务框架revolver:RUDP(可靠UDP)算法详解(2)

除了发送函数以外,发送缓冲区对象还会响应来自网络的on_ack和on_nack消息,这两个消息分别是处理正常的状态报告和丢包情况下的网络报告.如果收到on_ack,缓冲区对象会把已经接收端报告过来的报文ID全部从发送窗口中删除,然后调用attempt_send尝试新的块发送.如果收到的是on_nack,表示对端有丢包,则先会记录丢包的ID到loss_set中,再调用on_ack进行处理. 触发attempt_send还有可能是定时器Timer,定时器每5MS会检查一下发送缓冲区,并调用attem

高性能服务框架revolver:RUDP(可靠UDP)算法详解

数据块定义 在RUDP模块中,所有发送的数据被定义成RUDPRecvSegment 和 RUDPSendSegment结构,其中RUDPSendSegment是发送块定义,RUDPRecvSegment 是接收块定义.如下: //发送数据片 typedef struct tagRUDPSendSegment { uint64_t seq_; //块序号 uint64_t push_ts_; //进入发送队列的时刻 uint64_t last_send_ts_; //最后一次发送的时刻 uint1

高性能服务框架revolver:RUDP(可靠UDP)算法详解(3)

接收缓冲区相对比较简单,其主要功能是接收发送方的数据并生成接收块.块排序.丢包判断和反馈.读事件通知等.以下是接收缓冲区的定义: class RUDPRecvBuffer { public: ... //来自网络中的数据 int32_t on_data(uint64_t seq, const uint8_t* data, int32_t data_size); //定时事件 void on_timer(uint64_t now_timer, uint32_t rtc); //读取BUFFER中的

UDP可靠传输那些事

有空来论坛走走,发现讨论udp可靠传输又热了起来,有人认为udp高效率,有人认为udp丢包重传机制容易控制,还有朋友搞极限测试,当然也有人推销自己的东西,这里写一点我个人的看法. udp可靠传输其实非常非常的简单,我最开始接触udp可靠传输大约是在2005年,因为那时候开发FtpAnywhere,由于路由的映射和网关nat处理方面,认为udp具有天生优势,因此开始编写自己的udp可靠传输协议,好象那个时候已经有了udt,我也下了源代码看了下,不过很快就看不下去了,因为它用了定时器,加上跨平台处理

为什么 UDP 有时比 TCP 更有优势

随着网络技术飞速发展,网速已不再是传输的瓶颈,UDP协议以其简单.传输快的优势,在越来越多场景下取代了TCP,如网页浏览.流媒体.实时游戏.物联网. 1.网速的提升给UDP稳定性提供可靠网络保障 CDN服务商Akamai(NASDAQ: AKAM)报告从2008年到2015年7年时间,各个国家网络平均速率由1.5Mbps提升为5.1Mbps,网速提升近4倍.网络环境变好,网络传输的延迟.稳定性也随之改善,UDP的丢包率低于5%,如果再使用应用层重传,能够完全确保传输的可靠性. 2.对比测试结果U

UDP的崛起

随着网络技术飞速发展,网速已不再是传输的瓶颈,UDP协议以其简单.传输快的优势,在越来越多场景下取代了TCP,如网页浏览.流媒体.实时游戏.物联网. 1,网速的提升给UDP稳定性提供可靠网络保障 CDN服务商Akamai(NASDAQ: AKAM)报告从2008年到2015年7年时间,各个国家网络平均速率由1.5Mbps提升为5.1Mbps,网速提升近4倍.网络环境变好,网络传输的延迟.稳定性也随之改善,UDP的丢包率低于5%,如果再使用应用层重传,能够完全确保传输的可靠性. 2,对比测试结果U

再次对比TCP与UDP

免责声明:和往常一样,此文章的观点都属于'No Bugs'Hare(译注:一个网站) ,也许不一定和翻译者或者Overload编辑的意见一致.同时,翻译者从Lapine翻译到英语也具有一定的难度.除此之外,翻译者与Overload对于从阅读此文章所带来的后果或不作为明确不负任何责任. 原文地址:Once Again on TCP vs UDP 讨论TCP与UDP的好与坏几乎与Linux和windows的争辩有着一样长的历史.我一直支持一个观点,也就是:UDP与TCP都有各自的适用场景(比如:[N