今天2009-03-14
写这个算法,已经很久了,一直没有写得让自己比较满意。但也没有放弃。
前后写了三个版本。经过几次的重复,现在的算是比较满意了,所以想写点什么来让大家一同分享。
第一个版本基本上可用吧,
http://topic.csdn.net/t/20051208/23/4447596.html
这是2005年发布的贴子。
我现在总结一下,我是如何实现的过程及相关的原理。
首先我想到的就是tcp的滑动窗口,这确实是一个不错的算法,比较可行,我开始了模拟tcp,
TCP拥塞控制算法由不同组成部分:
(1)AIMD。
(2)Slow Start。
(3)对超时事件的处理。
具体可以查看
http://www.net130.com/netbass/RFCs/RFC2581.txt
今天先写到这里,有空接着写。
今天2009-04-04
刚把手上的事情做完,想想接着写吧!
在这个算法中,最重要的是有几个量:
rto 超时时间,对于每个分组。
basertt 的测量。
我第一个版本就是模拟tcp来完成的,对于象我们家里的网络来说,还行,因为只有我一个人来用,不受到其他人影响,另外我测试的主机速度是100m的服务器,所以,ack丢掉的可能性也较小,测试的效果还比较理想。
我家里是1.5m电信的adsl,上传最大速度,理论上是52~54kB,
而实际的算法,平均速度达到了49~50kB的速度,我当时比较满意。
大约二年过去后。。。
有一次和网上一个朋友比较传输算法的时候,发现他的算法更好,基本上是52kB,让我非常吃惊。
后来,我又有了二台新的测试服务器,一共有三台服务器,其中两台是电信服务器,一台是网通服务器。
三台服务器上,二台电信服务器上,我的算法表现都还可以,基本上是50k左右。
而在第三台网通服务器上,速度只有10k左右,而网友的算法可以达到40k左右,这让我很失望。
我开始查找相关的资料,一直未果。
又有三四个月过去了,我尝试过很多算法,看过很多资料,包括各种tcp的实现,比如sack,vegs, htcp,等。
最后我选择了vegs + sack来实现我的算法。
今天就到这吧。
今天2009-05-13
有一段时间没有写了。目前的版本基本上已经非常好了。
vegs可以精确控制当前传送的最大流速,可以确定发送窗口大小。
另外,sack可以实现协带多个ack,防止ack的丢失,从而可以大大提高效率。
最近又有二个比较有意义的更新
一个是对于周期性发送新数据的问题,目前考虑到每收到一个ack时,表明管道中有一个数据分组离开网络,可以立即追加一个新的分组。所以把周期性发送1个管道的数据量改成半个管道数据,可以大大提高,双工时的效率和公平性。使双向传输更具公平性和友好性。
另外一个调整是重传策略,目前把重传包放在一个fifo的数组中,总是重传最先传送的包是否超时,达到防止过多的重传。对网络差的情况下,效率提高明显。
以下是我的工作流程 图:
https://p-blog.csdn.net/images/p_blog_csdn_net/wwwllg/EntryImages/20090513/image001.gif
ACK设计
同时回传,多个包的ack这样,可以弥补其中某些ack丢失。
https://p-blog.csdn.net/images/p_blog_csdn_net/wwwllg/EntryImages/20090513/image001633778028805625000.gif
从上图应该可以知道,可以迷补因为1,2,3的ack丢失造成1,2,3的不必要重传,从而节省了重传代宽增加了传输效率。
2009-08-22
另外需要提的事情是,快速重传,当某个包,联续收到3~4个,sack的时候,可以断定,此包已经丢失,可以在大于一个rto的情况进行重传。
窗口大小,现在增长的算法作了一些调整。vegas在小于diff的时候,会不断增大窗口,这样会出现一个问题。
当缓冲全部用完,而最前面的序号没有确认的时候,会造成一种现象,实际可发数据变得非常少,远小于发送窗口大小,这样rtt会因为数据发送量的减少,而变短。而由于rtt变短,造成发送窗口的更加变大,当窗口大小大于实际的流量代宽的时候,更容易发生丢失,从而造成一种死循环。
改进方法是:增加一个最大窗口,当发送窗口在最大窗口一半时,如果发生包丢失,窗口大小立即--。而小于最大窗口一半时,+=1/wndsize.
当没有丢包时,如果小于最大窗口一半时wnsize ++,大于一半时 += 1/wndsize.
这样有什么好处呢?当接近伐值时,我们可以慢速度增长,和发生拥塞时快速度减少发送数据,使发送流量接近最大发送速度。
当然事情都有两面,在那种丢包率本身就很高的网络,这种处理方法会大大的降低发送速度。原因很简单。因为丢包很多,所以窗口不能变得很大。这种网络只有尽可能的多发数据,这样有效数据的绝对量会多一些,当然,丢包会更多一些。这样会浪费很多代宽,在多个流竟争的条件下,会严重影响其他流。而我们的算法是一种保守的处理方法,我们的算法是扶强不扶弱。从而可以减少浪费。
从实际算法实现和效果来说,是非常不错的。
在一般的adsl设备上,如果网络良好的情况下,基本上丢包为0,发送几十m数据,丢包可能在10k以下。
此算法,可以用在文件传输,和即时通讯领域。
在很多版本以前我已经超过udt和raknet. 这些都是通过大量主机测试得出来的结论。
如果有人对udt或raknet有所改进,欢迎指正。
欢迎计论rudp方面的技术,我的msn [email protected] , qq: 24508609
需要可执行程序,和您的算法对比的,可以向我索要,我的邮箱[email protected]