inc宏定义了窗口更新函数,按循环式前进更新。
帧结构定义如下:
typedefstructFRAME{
unsignedcharkind;
seq_nrack;
seq_nrseq;
packetdata;
unsignedintpadding;
}Frame;
为了体现出网络层数据包与帧结构的不同,对帧结构进行再次封装。
不过由于程序没用到网络层方面的东西,因此网络层包结构只包含帧结构字段,不包含其他字段。
其定义如下:
typedefstruct{
unsignedcharinfo[PKT_LEN];
}packet;
PKT_LEN帧结构最大长度。
#pragmacomment(lib,"Protocol.lib")
该句用来导入静态链接库Protocol.lib
boolno_nak=true;
该全局变量用来判断表示没有NAK,可以用来提高发送效率。
staticintphl_ready=0;
静态变量用来标示物理层状态,物理层Ready用phl_ready=1表示,未准备好用0表示。
Event表示到达事件类型,arg打印日志时候库函数用到,len用来保存返回的包长度。
intevent,arg,len=0;
帧变量r定义如下:
Framer;
其他定义。
seq_nrnext_frame_to_send;
seq_nrack_expected;
seq_nrframe_expected;
seq_nrtoo_far;
seq_nrnbuffered;
packetout_buf[NR_BUFS];
packetin_buf[NR_BUFS];
boolarrived[NR_BUFS];
next_frame_to_send标示下一个要发送的帧的序列号。
ack_expected标示下一个要接受的ack序列号。
frame_expected标示下一个要接受的帧的序列号。
too_far用做判断。
nbuffered定义当前Buffer位置,防止越界,超过NR_BUFS长度时限制从网络层接收包。
out_buf和in_buf分别表示out包和in包缓冲。
其最大值均标示为NR_BUFS。
arrived一维数组用用来表示Arrived情况,到达为1,否则为0.
2、模块结构分析
staticintbetween(seq_nra,seq_nrb,seq_nrc);
判断序列号是否在窗口内。
staticvoidsend_data();
根据发送数据类型是“FRAME_DATA”,“FRAME_NAK”,“FRAME_ACK”
来发送不同的数据,函数参数参考程序源码,在此不列出。
staticvoidput_frame(unsignedchar*frame,intlen)
进行CRC校验,同时添加特定的标识字段然后上交给网络层。
3、算法流程(见下页)
五、实验测试
Go-back-N性能测试记录表
序号
命令
说明
运行时间(秒)
效率(%)
备注
A
B
1
datalinkau
datalinkbu
无误码信道数据传输
1800
52
70.5
发送窗口大小7、定时器时长2800
2
datalinka
datalinkb
站点A分组层平缓方式发出数据,站点B周期性交替“发送100秒,停发100秒”
1800
41.5
57.5
同上
3
datalinkafu
datalinkbfu
无误码信道,站点A和站点B的分组层都洪水式产生分组
1800
96.9
96.9
同上
4
datalinkaf
datalinkbf
站点A/B的分组层都洪水式产生分组
1800
74.5
74.7
同上
5
datalinkaf–ber1e-4
datalinkbf–ber1e-4
站点A/B的分组层都洪水式产生分组,线路误码率设为10-4
1800
25.8
26.2
同上
6
datalinka
datalinkb
站点A分组层平缓方式发出数据,站点B周期性交替“发送100秒,停发100秒”
1800
27.1
43.4
定时器时长设为2000
第一组测试(最优:
窗口大小MAX_SEQ=7、定时器DATA_TIMER=2800)
(1)、au&bu
(2)a&b
(3)afu&bfu
(4)af&bf
(5)af&bf误码率为1e-4
第二组测试(窗口大小MAX_SEQ=7、定时器DATA_TIMER=2000)
(6)a&b窗口大小7、定时器时长2000
SLECTIVEREPEAT性能测试记录表
序号
命令
说明
运行时间(秒)
效率(%)
备注
A
B
1
Slectiveau
Slectivebu
无误码信道数据传输
1800
53.3
96.97
发送窗口大小16、DATA_TIMER=3800
ACK_TIMER=1100
2
Slectivea
Slectiveb
站点A分组层平缓方式发出数据,站点B周期性交替“发送100秒,停发100秒”
1800
52.3
94.0
同上
3
Slectiveafu
Slectivebfu
无误码信道,站点A和站点B的分组层都洪水式产生分组
1800
96.97
96.97
同上
4
Slectiveaf
Slectivebf
站点A/B的分组层都洪水式产生分组
1800
95.0
94.6
同上
5
Slectiveaf–ber1e-4
Slectivebf–ber1e-4
站点A/B的分组层都洪水式产生分组,线路误码率设为10-4
1800
60.6
59.5
同上
6
Slectivea
Slectiveb
站点A分组层平缓方式发出数据,站点B周期性交替“发送100秒,停发100秒”
1800
46.5
85.5
发送窗口大小16、DATA_TIMER=2000
ACK_TIMER=1100
7
Slectivea
Slectiveb
站点A分组层平缓方式发出数据,站点B周期性交替“发送100秒,停发100秒”
1800
52
70.5
发送窗口大小16、DATA_TIMER=5000
ACK_TIMER=1100
第一组测试(当前最大窗口数是MAX_SEQ=31,即发送窗口为NR_BUFS=(MAX_SEQ+1)/2=16,发送数据帧定时器时长为DATA_TIMER=3800,ACK等待定时器时长为ACK_TIMER=1100。
)
(1)au&bu
(2)a&b
(3)afu&bfu
(4)af&bf
(5)af&bf误码率为1e-4
第二组:
(当前最大窗口数是MAX_SEQ=31,即发送窗口为NR_BUFS=(MAX_SEQ+1)/2=16,发送数据帧定时器时长为DATA_TIMER=2000,ACK等待定时器时长为ACK_TIMER=1100。
)
第三组:
(当前最大窗口数是MAX_SEQ=31,即发送窗口为NR_BUFS=(MAX_SEQ+1)/2=16,发送数据帧定时器时长为DATA_TIMER=5000,ACK等待定时器时长为ACK_TIMER=1100。
)
a&b
六、实验结果分析
(1)描述你所实现的协议软件是否实现了有误码信道环境中无差错传输功能。
能实现。
因为采用了CRC校验和重传技术,如果有错误的话能得以被发现和纠正。
(2)程序的健壮性如何,能否可靠地长时间运行。
程序的健壮性较好,在高负荷和高误码率等条件下均能工作。
只是负荷不同,效率不一样。
(3)协议参数的选取:
滑动窗口的大小,重传定时器的时限,这些参数是怎样确定的?
根据信道特性数据,分组层分组的大小,以及你的滑动窗口机制,给出定量分析详细列举出选择这些参数值的具体
实验中物理层提供了一种字节流传输服务,使用字节填充技术成帧,分组长度固定为256字节。
滑动窗口的大小直接涉及到信道利用率和数据拥塞问题,若太小,将导致信道利用率过低,信道中长时间没有数据传送;若太大,数据发送过快,将造成接收方数据链路层来不及处理,数据物理层及信道发生拥塞现象导致数据丢失,出错率增加。
滑动窗口的大小N,信道传输时延a,发送率c,帧大小f应满足关系式:
N>=[2a+2*(f/c)]/(f/c),同时通过实际测试的结果分析得到合适的N值,防止N过大,最终值设为7。
重传计时器的时限涉及到重传的响应时间,若太大,将导致重传等待的时间过久;若太小,将导致较为频繁的重传,两种情况均将导致信道利用率下降。
通过实际测试,设为2800ms左右时效率最高。
协议六与协议五确定方法类似。
(4)理论分析:
根据所设计的滑动窗口工作机制(Go-Back-N或者选择重传),推导出在无差错信道环境下分组层能获得的最大信道利用率;推导出在有误码条件下重传操作及时发生等理想情况下分组层能获得的最大信道利用率。
给出理论推导过程。
理论推导的目的是得到信道利用率的极限数据。
为了简化有误码条件下的最大利用率推导过程,可以对问题模型进行简化,比如:
假定超时重传的数据帧的回馈ACK帧可以100%正确传输,但是简化问题分析的这些假设必须不会对整个结论产生较大的误差。
因为需要携带帧讯息,所以最大的信息利用率约为256/(256+4+4+2)*100%=96.24%。
因为信道的最大比特率为8000bps,所以每传输一个字节耗时1ms,每帧的附加讯息固定为10,耗时10ms,若出现转义字符,将可能增加时间。
假设信道上始终有数据需要传送,在10-5错误率的信道上,在100000个比特中可以传送100000/(260*8)=48个数据包,则每48个数据包将有一个出错,假设每出错一次,在限定时间内可以重传该帧为正确帧,则每传送48个数据包需传输48+1+1=50次,此时信道利用率为48*250/(50*260+10)*100%=92.24%,但由于程序设计的原因,当一个数据包超时后,往往需重复多次传输给数据包造成信道的浪费。
若重传k次,则信道利用率为48*250/[(49+k)*260+10]*100%,其中,平均重传10次,信道利用率约为78.18%。
在10-4错误率的信道上,出错率提高到大约每5个帧就有1个出错,在ESC/FLAG模式下信道利用率的极限值为4*250/(6*510+10)*100%=32.57%。
(5)实验结果分析:
你的程序运行实际达到了什么样的效率,比对理论推导给出的结论,有没有差距?
给出原因。
有没有改进的办法?
如果没有时间把这些方法付诸编程实施,介绍你的方案。
在洪泛模式下,利用率与分析值大致一样。
其它情况下,由于不总是负载很重,所以利用率会低一点
(7)存在的问题:
在“表3性能测试记录表”中给出了几种测试方案,在测试中你的程序有没有失败,或者,虽未失败,但表现出来的性能仍有差距,你的程序中还存在哪些问题?
程序没有失败,稳定性也很好。
但是测试性能距离老师给的参数还存在一些差距,估计在参数方面可能存在更优的取值。
七、总结和心得体会
经过这次实验,我们对数据链路层几个重要的协议有了更深入的了解。
对GobackN和选择重传的效率有了具体化的分析和定位。
其次编程能力也有了提高,特别是对基于别人提供的封装接口的应用能力有了很大提高。
用别人提供的库,首先要对动态库的实现有具体了解,要忽略实现的具体细节等等。
还有打印日志对程序调试与性能分析也很重要,特别是调BUG的时候,输出某些变量的值和日志的信息对于调试程序有很大帮助。
如饮茶水,冷暖自知。
有努力就会有收获的。
大三咯。
Comeon!