计算机网络实验3.4-基于UDP服务设计可靠传输协议(性能测试)

计算机网络实验3.4-基于UDP服务设计可靠传输协议(性能测试)

实验要求

基于给定的实验测试环境,通过改变延迟时 间和丢包率,完成下面3组性能对比实验:

(1)停等机制与滑动窗口机制性能对比;

(2)滑动窗口机制中不同窗口大小对性能的影响;

(3)有拥塞控制和无拥塞控制的性能比较。

  • 控制变量法;

  • 性能测试指标:吞吐率、时延,给出图形结果并进行分析。

实验环境及测试流程

Windows 10 MinGW w64 9.0

协议设计等可参见lab3.1

测试中发现,输出中间信息(如窗口大小丢包信息等)会显著影响传输时间,传输时间较短时更为明显。同时不同的实现输出的内容和数量也不一致。因此下面的性能测试中均去除了传输过程中所有输出信息。

每组数据测量三次,取平均值。

经测试,吞吐率与文件类型无明显关联。故所有测试均使用提供的helloworld.txt,文件大小1552320字节。所有测试与吞吐率相关指标均用该文件净传输时间表示。

吞吐率可计算如下:

Throughput rate=(double)file_len*1000/(timer_end-timer_start)) B/s

性能测试

停等协议&滑动窗口

停等协议

停等协议下,改变丢包率和延时测得数据如下所示(单位:ms):

丢包率 0 1 2 3 50
0% 1209 24553 28056 31249 117252
1% 34148 63867 65102 66329
9% 190942

可以从数据中初步探索延迟和丢包率对传输时间的影响力度。

滑动窗口

GBN

在窗口大小为10,超时时间为1s时,测得数据如下所示(单位:ms):

丢包率 0 1 2 3 50
0% 1301 29799 32112 39832 115665
1% 37429 69002 75104 78379
9% 250775

image-20221230215757564

可以看到,在实验环境下,GBN的整体表现甚至不如停等协议,即便是没有丢包和延时的条件下也是如此。猜测在实验条件下传输速度主要取决于接收端的接收速度。即使发送端可以“并行”发送,但由于接收端仍然需要等待和停等协议接近相同的超时时间接收丢失的包,因此传输速度并没有相差多少,反而由于GBN使得接收方不得不处理失序的包,从而耽误了更多的一些时间。

同时也在实验中尝试在接收端对两次收包的间隔进行计时,发现丢包率设为0%时间隔仅为1-2ms,而仅仅将丢包率设为1%,延时仍为0s的前提下,正常接收(不涉及丢包时)的时延达9-15ms不等。猜测这个现象与路由器程序的实现有关。因此,0/0%的高吞吐率实际上在这个实验中并没有参考价值。

c++
//"blocking" receive here
while (rdt_rcv(rcvpkt)) {
    single_pkt_timer2=clock();
    cout<<"ack_between_time: "<<single_pkt_timer2-single_pkt_timer1<<endl;
    single_pkt_timer1=clock();
    ...handle pkts...
    }

另外,在丢包率为10%,窗口大小为10时,路由器总是会丢弃同一个包,因此会造成无法正常接收的情况。因此采用9%来指代丢包率极高的情形。

滑动窗口参数探索

窗口大小比较

根据上面的探索,在探索滑动窗口参数时,控制延迟和丢包率分别为0ms和1%,以尽可能减少等待时间的前提下验证其正常功能发挥,同时避免路由器程序bug的影响。

GBN在不同窗口大小情况下的数据如下所示:

窗口大小 2 5 10 20 30
传输速率(ms) 36192 37274 37429 38220 47513

image-20221230214521654

可以看到,当窗口大小较大时,制约传输速度的因素主要是接收端接收的速度,因此单纯的增大窗口大小并无益于增加传输速度,如下所示为窗口大小为40时的情况:

image-20221230214007362

当然也注意到,即便窗口大小设为2,性能也不如停等版本。

不同算法的比较

而对于SR来说,这种现象则出现的更为严重,由于接收端需要对更多的情况进行判断和处理,且以至于在实验条件下疲于应付发送端发送的速度,因此出现了明明没有丢的包,由于接收方没有及时处理并且返回ACK,导致发送端循环进行超时重传,传输无法正常进行。如下图所示:

image-20221230220200564

image-20221230220316189

出现了这种情况后,尽管窗口仍旧可以移动,但由于接收方不得不处理大量重复的分组,导致恶性循环:越重发越接收的慢,越接收的慢越重发。不久就会出现重发的包远大于事实上需要的包的局面:

image-20221230221445403

解决方法可以是增大判断超时的时间。但是很明显,这会增加传输时间,而且这也并没有解决根本问题,并且会使正常情形下丢包的代价增加。

因此我们看到,由于发送和接收速率相差太大,“流量控制”也没能控制住。只好强行压制发送端的速度,查看在接收和发送基本对等的情况下滑动窗口的表现:

具体做法是在发送每一个while循环手动添加延时,模拟上层交付流较缓慢的情况:

c++
// wait for a while to send next packet (simulating content processing)
// this is to avoid sending too many packets at once
Sleep(10);

这时SR算法顺畅的进行了接收:

image-20221230222352630

在添加发送延时后,控制变量(延迟和丢包率分别为0ms和1%)并测量吞吐率:

窗口大小 2 10 40
停等 65120 65120 65120
GBN 46008 46335 49433
SR 39249 40451 48574

image-20221230231420543

可以看到,此时滑动窗口发挥了其应有的作用。

拥塞控制性能探索

在实验3.3中提到,在GBN上实现RENO算法可以不改变发送端(累积确认,不缓存),但这样带来的问题是这种情况下快速重传当前期望的包只是解决了“眼前的问题”,其余的包迟早还要超时重传,因此尽管进⾏了拥塞控制,但重传的⾏为在实际⽹络环境中事实上加剧了拥塞。因此对接收端进行了改进,使其在保持累积确认的基础上对包进行缓存。(详细可参见lab3.3

下面以窗口大小为10,延迟和丢包率分别为0ms和1%为例,对各算法性能进行对比:

停等 GBN SR RENO-no-cache RENO-cached
65120 46335 40451 50843 25224
image-20221230233213265

可以看到缓存的RENO-cached算法性能最好,因为其在实验环境下完全避免了重传,使接收端的负担最小。如下图所示:

image-20221230233838694

(在真实环境下大部分情况一次丢一个包的前提下也能取得很好的表现,如果一次丢多个包,可以考虑New RENO,如果希望更细致的预测网络环境,Cubic等算法还可以做的更好)

总结

这学期的计算机网络作业层层相扣,并且有效的将理论与实践相结合。通过这几次实验,我不再停留在机械的记忆TCP各个过程的细节,而是贯通性的理解了一个可靠数据传输协议设计的过程,以及如何去应对一些特殊情况或进行优化。当然,像TCP这样复杂的协议设计远非我们简单通过几个实验能够完全理解透彻的,就比如拥塞控制算法就有很多优化的方向,在本系列实验中也没能深入探究。

这次实验采用git进行管理,虽然说还不甚规范,但也让我更加熟悉了git的工作流,为以后进行更大项目的开发做准备。

image-20221230234222414

源代码

github


计算机网络实验3.4-基于UDP服务设计可靠传输协议(性能测试)
http://lunaticsky-tql.github.io/posts/55174/
作者
Lunatic sky
发布于
2022年12月31日
许可协议