udp如何确保可靠存储_udp 可靠传输_udp实现可靠数据存储

电脑杂谈  发布时间:2020-03-04 11:01:11  来源:网络整理

udp实现可靠数据传输_udp 可靠传输_udp如何保证可靠传输

有空来论坛走走,发现讨论udp可靠存储又热了出来,有人认为udp高效率,有人认为udp丢包重传机制容易控制,还有朋友搞极限测试,当然还有人推销自己的东西,这里写一点我个人的想法。

udp可靠存储其实相当特别的简单,我很开始接触udp可靠存储大约是在2005年,因为那时候开发FtpAnywhere,由于路由的映射和端口nat处理方面udp如何保证可靠传输,认为udp具有天生优势,因此起初编写自己的udp可靠存储协议,好象那个时候终于有了udt,我也下了源代码看了下,不过随后就看不下来了,因为它用了定时器,加上跨平台处理,导致它的代码,反正我看到更乱,理不出一个完整的逻辑图。但是机理和tcp的基本一样,并没有什么特殊的。后来我写了我自己的第一个udp可靠存储类,QTUdp,这个是很简单的,也就是和tcp一样,实现2点之间的传输,并不是我今天写的多点之间无中心p2p传输,效率很好,但是后来的编码我还没有养成现在的习惯,用了长期的DWORD之类的数据定义udp如何保证可靠传输,包括包的定义,从那时角度看,不及格,不过至少它可以实用,并融合到了FtpAnywhere软件中,在安装和运行过程中,慢慢的统计和看到udp包的存储中,最影响性能的个别以及其它一些细节,后来的ut 1.x多点传输协议就是在QTUdp基础上开发的,在至目前 ut 2.x , phoenix 2.x,实现了几个跨越。

请相信,可靠udp传输从来都不是高效率可靠传输的代名词,影响传输强度的更重要原因在于,sendto函数,每次只能投递一个mtu长度的包,频繁的平台调用极大的制约了极限性能,也许你会说,udp默认可以达到64KB,你可以投递大包,是的,可以投递,但是因为网络上mtu设备的限制,大包会被拆成小包,如果你定义一个包大于mtu,那么当其中任何一个小包发生丢包的之后,会导致整个包必须重传,这个开销十分巨大,特别是在Internet上,而采取mtu大小限制内的包进行存储,丢失一个,只应该重传一个,开销小的多。udp可靠存储的自定义校验是另外一个限制,为了防止虚假的udp包,我们必须在我们自己的靠谱udp包中加入自定义的校验,这个校验步骤也直接影响到性能,最快的是直接套用crc32校验,由于现在cpu指令集对这个计算进行了改进,因此它的计算速度近乎是很快的,但是代价是,人家要破解或者伪造你的udp包也很容易,因为算法是透明的,以前暴出tcp伪造漏洞只是这种,由于它的包构成是透明公开,唯一有保密性的是序列号,结果有些系统初始序列号存在规律,结果就造成了安全问题。最后,发送和接收,由于是在应用层进行[无论你是采用api epoll select overlap io,最终的执行都是在应用层],这个发送-确认过程中,由于应用层不是象tcp/ip协议栈那样在内核态运行,因此或许有推迟,不过,目前的cpu核心数目跟频率,这个制约在工业应用[internet 等]已经几乎可以忽视,唯一造成妨碍是在进行本机极限性能检测中。TCP的精度应高过udp可靠存储,因为它的send函数,几乎每天都可以拷贝几十KB,当然你可以将缓冲调整的巨大,例如几百KB或者几MB,但是默认情况下的几十KB足够了,想当于几十次调用udp sendto , 而tcp只应该调用一次,其次,tcp的包处理是在内核态进行,确认只是内核态,这就从而与应用层的udp可靠存储拉开距离,更何况硬件层的改进了. 那么,你可能会认为,为什么书上说udp性能好呢?其实这是对于不可信udp传输,并且是网关 大包,例如

udp实现可靠数据传输_udp如何保证可靠传输_udp 可靠传输

char buffs[32*1024];

memset(buffs,0,32*1024);

sendto(s , buffs,32*1024,.... 发射后不管,无论是否丢包

udp 可靠传输_udp实现可靠数据传输_udp如何保证可靠传输

象那样发包,效率就会达到tcp,不过,主要就是包头大小的差距.

使用udp可靠存储的目的是为了它的灵活性,在这些协议传输中,例如,远程视频流存储,jrtlib,通常分为关键帧和普通帧,关键帧的丢失,会导致普通帧失去作用,这个之后就必须使用udp的靠谱传输+不可信存储,实现方式是首先以可靠机制投递关键帧,在关键帧处理完成后,剩余的时间用非可靠模式投递普通帧,每隔指定时间重复这一步骤. 如果使用tcp,这个效果就不好了,因为网络带宽就那么多,而且带宽变化巨大,把所有的关键帧和普通帧都进行可靠存储,可能造成不顺畅,网络阻塞等.

关于udp的穿透能力,也就是传说中的打洞,这根本是个伪命题,有人还在那儿弄什么测试说打通了4种 nat 模型, 你觉得或许吗? 还有人用猜端口的方式进行打洞,我了个去,工业上可如此用? udp的穿透其实完全取决于路由[网关]的配置,国产的商用以及soho针对p2p进行过调整,但是你用cisco 等的小型设施进行打洞看看,为了保护用户的安全,一般管理员都设定了高安全非透明,通常,就算是外部同一台电脑,同一个udp端口,发送给不同的目标ip数据包,路由都会随机重新分配一个端口,打洞根本不可能顺利的. 所以,如果你为了nat处理而使用udp,建议你还是放弃吧,直接使用tcp+upnp就行.

udp如何保证可靠传输_udp 可靠传输_udp实现可靠数据传输

关于udp可靠存储的功耗,有人说使用epoll , overlap io 等,效率低于使用select模型, 我可以按照我的这几年开发的历程和检测结果告诉你,在校准方式,投递模式或者数据处理逻辑相同的状况下,多核心cpu平台下,本机强度差异不少于1%,而即使使用在Internet上,效率差别无限接近0,现在是cpu过剩的年代,linux windows的调度下,如果没有内核态运算,那么都会从期待的线程中挑选一个,你不要以为从内核态切换到用户态是不需要开销的,这个花费同样巨大,频繁的调度同样影响性能,虽然不算在你的代码中而算在平台开销中. 当然,如果你必须在linux平台中同时运行apache等web服务,那效率差别会非常显著,因为进程跟线程太多,得不到第一时间的调度.

关于udp可靠存储下缓冲大小,说实话,我是第一次见识,最简洁的点对点 udp可靠存储,有人开了上百KB的缓冲,缓冲是个好东西,通常,缓冲越大,效率越高,因为一次投递的包数量多,IO性能就高,但是,这在Internet上是不注重的,这种实现我不知道是否经过严格的网络丢包和负载测试,在有商用路由小带宽上传方式下,如果有以及多个网络程序使用带宽,这个延迟参数变动相当频繁,不必要的重传率会特别高,最简单的测试方式,找个铜包铝网线,使用1 1对应的非标准接头法,一头接电脑,一头接路由,然后与Internet上远端进行测试,估计这个丢包重传的几率会高的可怕.

udp可靠存储比TCP的慢启动好?我想不必定,还是我里面那些网线做检测,如果采取迅速推进,在丢包严重的网络环境下,带宽浪费太离谱了,我调整我自己的udp可靠存储启动方式好多次,越来越觉得tcp的慢启动是相当有道理的,虽然恢复的慢,但是,它由于错误重传而形成带宽的浪费是相当小的. 当然,如果考虑到性能,还是可以适度调整的尽快.

udp实现可靠数据传输_udp 可靠传输_udp如何保证可靠传输

关于udp可靠存储的文件传输效率,这是个伪命题,这个极限是硬件本身产生的,首先,正常的udp可靠存储强度显然超过普通内存的读写盘速度,即使用memory map 技术对文件执行加速,还是跟不上udp本身的速率,其次,文件传输协议会妨碍到存储强度,最快的方式是哪个? 就是直接发送文件从起初到结尾,和流 [FTP数据连接 HTTP]一样,这是很快的,但是一般,为了防止数据差错,会对文件传输内容进行分块传输,并加入校验.这就影响到了传输效率. 你说一辆公共汽车是从起点至终点直达快?还是一站站的停过去快?很明显,第一个假设脱离实际的.

关于udp可靠存储和cpu的关系,有吗?肯定有,但是在普通应用下,基本没妨碍,只有在追求极限,例如本机测试,2G+光钎网络等,才会有显著的妨碍,可问题是,如果你的服务器[电脑]接入的是2G+光钎,你这服务器得什么硬件配置? 在通常应用下,cpu和存储开销以及错误的丢包重传才是第一位的. 如果一个udp可靠存储,100mbps网络下,必须要Intel piii 1Ghz以上,那在这个基础上研发起来的应用或许比现今的电脑游戏还吓人了. 如果不是多对多[因为这个逻辑比普通点对点udp可靠存储复杂的很多],普通的点对点udp可靠存储, 给几个以前的测试数据, QtUdp ,环境是Pentium M 1.7G[单核心], Ati xpress主板 768m ddr2 533[单通道] , 本机器模拟传输以前测试的数据至少在 78MB/s , MTU=1380 , 缓冲是 17 * MTU. , CPU开销大约是75%, 如果使用至今双核心,估计可以翻倍. 你可能会觉得这个数字很低,但是请注意当时的硬件环境,这个速度早已达到udt好多好多了. 最基本的点对点udp可靠存储,标准crc32校验,以现在的软件环境, i74核心, DDR3 1600 , 加上我们的一种特殊包处理技术,本机器UDP小包[1400]可靠存储的极限至少在270MB/s,如果需要提高,估计只能跟ms 的IIS一样,编写网络驱动了,但是x86处理器和内存速度始终在提升,说不定明天主频直接翻倍了...

其实,我转向udp可靠存储的一个非常重要因素,是IPV6取消了存储中ip层的数据校验,这造成tcp层完全负担起了数据校验任务,TCP数据能否还像IPV4下这么可靠,需要加个问号了,虽然IP层原本的差错率非常低,但是更改掉校验,直接带来的风险到底有很大,并没有经过实践的检测,靠ipv6实验网络得出的是理论结果,也许有两天会出现一种突破性的IPV6 TCP伪造技术. 而即使采取udp可靠存储,由于udp本身有校验,加上我们自己设计的校验和序列号,这个可靠程度完全达到了IPV4 下的TCP,更别提IPV6下的TCP了.

udp可靠存储,其实相当简洁,只要你有tcp/ip的基础,最简洁的点对点udp可靠存储是相当易于编写的,无非就是封包,校验,发送,确认,重新组包,接口可以模仿tcp的几个函数,这其中的一个难点是,判断是否必须重发,这还要按照当时包的确定时间来计算本包,如果你不期望那么复杂,也可以,经验数字 [不适合网通到电信], 第一次的重传时间 750 ms , 第二次是 1600 , 以后经常都是 2000 , 虽然不科学,但是用这个延迟数字,可以确保你足够的存储强度[即使存在小几率丢包],也不会产生长期的重传,当然最好的方式是从之前包的延迟来推导.

总之,udp可靠存储没这么复杂和奇特,它相当简洁,而且,它的效率也没有各位想象中的这么高,可能会让大家难过,但是,它很可爱,你可以轻易的展现你自己的包,实现各类扩展,其中的取舍完全在于聪明的你.


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-142956-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...