UDP大块数据传输测试

news/2024/5/17 15:51:09 标签: udp, 网络协议, 网络, tcp, liigo, c#, ftp

前一阵子我对UDP传输大块数据方面做了一些尝试,在本文中总结了一些失败的教训。
对于本文所述“大块数据”,我定义为大小在数MB至数GB之间的数据块。数据可以在内存里,也可以来自文件。

方案1:逐包请求

此方案采用逐包请求模式,先发请求,然后等待接收对方回复,如此循环请求接收。好处是简单粗暴,流程很容易控制,超时未收到就重复发当前包。

1.0 每包载荷大小固定为1KB

考虑到太网最大传输单元(MTU)通常被设置为1500,到了UDP这一层还剩下1472字节,载荷在此范围内可最大程度的避免IP层报文分片,提高传输效率。我们这里确定载荷大小为1KB,再加上应用层消息头也能确保不超过1472字节。

经测试,采用固定1KB载荷的方式,循环发送接收,稳定性是很好的,能实现基本功能,但是传输效率很差,大量时间消耗在等待发送等待接收。

1.1 每包载荷大小固定为32KB

人们联想到最大传输单元(MTU),往往望文生义以为报文载荷不能超过MTU,其实不然,超过也是可以的,IP层仍然可以分片发送,只要系统协议栈发送缓冲区足够大,都是可以发出去的。

我改进1.0中的方案,载荷大小从1KB增加至32K甚至更大。经测试当32K(加上消息头略大于32KB)时,通常也能够稳定发送接收,但是,它挑网,例如在公司里成功率比较高,而在家里成功率就比较低。而且还往往遇到奇怪的现象,例如,前面请求传输了一万包都挺正常的,到第10001包就死活收不到回复了,延时加重试多少次也不管用。调试发现,Server端收到了请求也发出了回复,是Client端收不到,所以猜测是丢在半路了。

总之这个方案还是不行,虽然速度上去了,但是挑网,稳定性不好,某些情况下甚至连基本功能都无法完成。

1.2 动态调整载荷大小 1K~32K

考虑到1.1方案中某一包会卡死,始终收不到回复,延时+重复请求不管用。我决定尝试动态调整载荷的方案,32K包触发多次失败后,降低至16K,不行的话继续降低,直至1KB。

这样做出来的程序,能保证基本功能,完成数据传输,但是因为失败率还是挺高,不断降速导致传输性能也很差,无法接受。

方案2,单次请求批量接收

再改一下方案,把整块数据拆分为1MB为单位的子块,客户端请求一次子块,服务端批量回复,将该子块拆分成1KB的包循环发出去。这样避免了客户端请求报文的发送次数,估计能提高传输性能。

实测不然,稳定性不行,还挑网。服务端发快了不行,容易把自己系统的发送缓冲区打满,想加延时又不知道该延时多少,想找一个实测可行的数,换一个网又废了。再考虑到UDP不保证数据到达也不保证报文顺序,应用层把这些东西做完,代码复杂度又上了一个数量级,恐怕也是得不偿失。

总之,这个方案也不行,速度较快,不稳定,网络适应性查,代码逻辑复杂。

方案3,TCP… FTP…

反思当初选用UDP,不就是想简单粗暴吗,不需要考虑粘包拆包,来了就是一个完整的报文,代码逻辑很简单,性能还过得去,就可以了。但是做到最后发现,要么性能太差了无法接受,要么挑网太不稳定了无法接受,要么逻辑太复杂了无法接受。初步的结论是UDP只适合做小数据收发,不太适合大数据量传输(QUIC/ENET那种二次开发UDP除外)。

其实还不如回归TCP,前期自己稍微麻烦点做报文边界隔离和拆包,后面很多事情都省事了。TCP支持自动重发,支持顺序到达,不香吗?做到媲美FTP的传输速度应该不难吧?


http://www.niftyadmin.cn/n/1864623.html

相关文章

【.Net CF開發答疑】設置光標狀態

在某些情况下,可能要執行一些耗費時間較長的後臺操作。爲了給用戶人性化的提示,我們可以將光標設置爲等待狀態。當該操作完成後,我們再將光標設置爲默認狀態(隱藏)。 代碼非常簡單,但必須事先添加System.Windows.Forms…

C#拾遗系列(6):迭代器

1. 示例: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; namespace NetTest { public class TestIteration { public void Test() { SevenColor colorIteration new SevenColor(); foreach…

让方法返回多个参数

刚刚写代码时,把一个方法写了100来行,并且还在不断增加中,于是准备把其中的代码段封装成一个方法。问题是,封装的这段代码要处理两个变量,于是google了一下。MSDN有办法。。。。。。 我们很清楚,一个方法只…

关于工作与生活的转帖

关于工作与生活的转帖 我有个有趣的观察,外企公司多的是25-35岁的白领,40岁以上的员工很少,二三十岁的外企员工是意气风发的,但外企公司40岁附近的经理人是很尴尬的。我见过的40岁附近的外企经理人大多在一直跳槽,最后…

什么是XML

XML是EXtensible Markup Language的缩写,扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于…

ASPxGridView中实现自动编号

ASPxGridView中实现自动编号 在ASPX文件ASPxGridView控件的合适处添加如下代码&#xff1a;<dxwgv:GridViewDataTextColumn Caption"序号" VisibleIndex"0" Width"25px"><DataItemTemplate><%# Container.ItemIndex1%></Da…

主机Redis服务迁移到现有Docker Overlay网络

“《麻雀虽小&#xff0c;五脏俱全》之主机现有Redis服务迁移到Docker Swarm Overlay网络&#xff0c;并搭建高可用容器集群。hello, 好久不见&#xff0c;之前文章记录了一个实战的2C分布式项目的改造过程&#xff0c;结果如下&#xff1a;其中Redis并未完成容器化改造&#x…