《计算机网络》选择重传协议
实验报告
1.实验内容和实验环境描述
实验内容:
利用所学数据链路层原理,设计一个滑动窗口协议,在仿真环境下编程实现有噪音信道环境下两站点之间无差错双工通信。信道模型为8000bps 全双工卫星信道,信道传播时延270毫秒,信道误码率为10-5,信道提供字节流传输服务,网络层分组长度固定为256字节。
实验环境:
Windows7—64位操作系统PC机VC 6.0
2.协议设计
数据结构:
数据帧
+=========+========+========+===============+========+
| KIND(1) | SEQ(1) | ACK(1) | DATA(240~256) | CRC(4) |
+=========+========+========+===============+========+
确认帧
+=========+========+========+
| KIND(1) | ACK(1) | CRC(4) |
+=========+========+========+
否定确认帧
+=========+========+========+
| KIND(1) | ACK(1) | CRC(4) |
+=========+========+========+
KIND:表示帧的类别
ACK:ACK序列号
SEQ:帧序列号
CRC:校验和
模块结构:
static inc(Uchar* a)
作用:使一个字节在0~MAX_SEQ的范围内循环自增。
参数:a,字节类型。
static between(Uchar a,Uchar b,Uchar c)
作用:判断当前帧是否落在发送/接收窗口内。
参数:a,b,c,均为字节类型,其中两个分别为窗口的上、下界,一个为帧的编号。其中,发送窗口的上界和下界分别为next_to_send和ack_expected,接收窗口的上界和下界分别为too_far和frame_expected,均定义在main函数中。
static void put_frame(unsigned char *frame, int len)
作用:为一个帧做CRC校验,填充至帧的尾部并将其递交给网络层发送。
参数:frame,字节数组,由除padding域之外的帧内容转换而来;len,整型,为帧的当前长度。
static send_frame_(Uchar fk,Uchar next_frame,Uchar frame_expected,Packet out_buf[])
作用:构造一个帧,并将其发送。
参数:fk,字节类型,为帧的内容;next_frame,字节类型,为帧的编号;frame_expected,字节类型,为希望收到的帧的编号;out_buf,二维字节数组,为缓冲区。
int main(int argc,char *argv[])
作用:主程式,包含选择重传协议的算法流程。
参数:argc,整型,表示命令行参数的个数;argv,二维字符数组,表示参数内容。
算法流程:
(a)物理层:为数据链路层提供的服务为8000bps,270ms传播延时,10-5误码率的字节流传输通道。为了仿真实现上述服务质量的信道,利用在同一台计算机上TCP Socket完成两个站点之间的通信。由于同一台计算机上TCP通信传播时延短、传播速度快、没有误码,物理层仿真程序在发送端利用“令牌桶”算法限制发送速率以仿真8000bps线路;在接收端误码插入模块利用一个伪随机数“随机地”篡改从TCP收到的数据,使得所接收到的每个比特出现差错的概率为10-5;接收到的数据缓冲后延时270ms才提交给数据链路层程序,以仿真信道的传播时延特性。为了简化程序,省略了成帧功能,数据链路层利用接口函数send_frame()和recv_frame()发送和接收一帧。
(b)数据链路层:发送方和接收方都维持一个窗口,窗口内部为可以接受的序列号。接收到的数据包被缓存起来,当按正确的顺序接收完毕后再提交给网络层。ACK信息通过数据帧捎带确认的方式传递,若遇到长时间无数据帧发送,则产生ACK超时事件(ACK_TIMEOUT),主动发送空的ACK帧。若长时间未收到ACK信息,则产生数据帧超时事件(DATA_TIMEOUT),发送方自动重传未确认帧;当出现帧丢失或校验错误时,接收方会主动发送NAK帧提示发送方立即重传。
数据链路层通过物理层提供的函数来利用物理层提供的服务。通过get_packet()函数从网络层得到一个分组;当数据链路层成功接收到一个分组后,通过put_packet()函数提交给网络层。
(c)网络层:利用数据链路层提供的“可靠的分组传输”服务,在站点A与站点B之间交换长度固定为256字节的数据分组。网络层把产生的分组交付数据链路层,并接受数据链路层提交来的数据分组。
3.结果分析
(1) 描述你所实现的协议软件是否实现了有误码信道环境中无差错传输功能。
我们的协议成功实现了有误码信道环境中无差错传输功能。如果收到一个损坏帧,在尚未发送否认确定的情况下,则捎带发送否定确认。并打印错误报告。如果已发送否定确认,则只打印错误报告,不重复发送否定确认。
(2) 程序的健壮性如何,能否可靠地长时间运行。
我们的程序成功连续运行半小时以上,并取得预定效果。具有足够的健壮性。
(3) 协议参数的选取:滑动窗口的大小,重传定时器的时限,ACK 搭载定时器的时限,这些参数是怎样确定的?根据信道特性数据,分组层分组的大小,以及你的滑动窗口机制,给出定量分析,详细列举出选择这些参数值的具体原因。
我们物理层提供的是字节流传输服务,使用字节填充技术成帧,分组长度为256字节。为了避免在有出错帧接收方要求重传时产生二义性,我们定义窗口大小为2^n-1,并且双方的窗口大小均为((MAX_SEQ+1)/2),这样的大小足够使用又不会有过于富余的空间浪费。滑动窗口的大小直接涉及到信道利用率和数据拥塞问题,若太大,数据发送过快将产生拥塞导致数据丢失,出错率增加,若太小则信道利用率降低,通过实验测试合适的窗口大小为16。
重传定时器时限涉及到重传的响应时间,太小会导致频繁重传,太大则重传等待时间太久,经过我们的试验测试,选取重传定时器时限定为3000毫秒,ACK 搭载定时器的时限为1000毫秒最合适。