1、云南大学软件学院计算机网络原理实验六实验报告实验六、传输层可靠传输协议GBN编程实验报告序号: 姓名: 学号: 成绩 指导老师: 一、实验目的:1、通过编写实现一个简单可靠的数据传输协议GBN的发送和接收代码,模拟可靠数据传输2、理解TCP协议可靠传输的差错检测、重传、累计确认、定时器的可靠传输策略。二、实验指导:参考教材。动画演示:三、实验要求:编程实现一个GBN传输协议的发送方和接收方两程序,采用编程语言不限,要求能将发送接收流程以及处理方法表现出来.1.实验流程图如下: 选择重传 Y N 2.实验截图与代码如下:截图:代码及注释:一、 GBN.h#pragma once#include
2、/基础功能模块的数据结构声明#define BIDIRECTIONAL 1 /* change to 1 if youre doing extra credit and write a routine called B_output */* a msg is the data unit passed from layer 5 (teachers code) to layer 4 (students code). It contains the data (characters) to be delivered to layer 5 via the students transport leve
3、l protocol entities. */struct msg char data20;/* a packet is the data unit passed from layer 4 (students code) to layer 3 (teachers code). Note the pre-defined packet structure, which all students must follow. */struct pkt int seqnum; int acknum; int checksum; char payload20;#define WINDOWSIZE 8#def
4、ine MAXBUFSIZE 50#define RTT 15.0#define NOTUSED 0#define NACK -1#define TRUE 1#define FALSE 0#define A 0#define B 1/网络仿真部分数据结构声明*struct event float evtime; /* event time */ int evtype; /* event type code */ int eventity; /* entity where event occurs */ struct pkt *pktptr; /* ptr to packet (if any)
5、assoc w/ this event */ struct event *prev; struct event *next; ;/* possible events: */#define TIMER_INTERRUPT 0 #define FROM_LAYER5 1#define FROM_LAYER3 2#define OFF 0#define ON 1/基础功能模块的函数声明*void ComputeChecksum(struct pkt *packet);/计算校验和int CheckCorrupted(struct pkt packet);/检查数据是否出错void A_output(
6、 struct msg message);/A端向外发送数据void A_input(struct pkt packet);/A端接收数据void A_timerinterrupt();/A计时器超时void A_init();/A端初始化void B_output(struct msg message); void B_input(struct pkt packet);void B_timerinterrupt();void B_init();/网络仿真部分的函数声明*void init(); /初始化仿真器float jimsrand();/随机数发生器0,1/处理事件列表部分的函数声明*
7、void generate_next_arrival();/产生下一个到达的分组void insertevent(struct event *p);/向事件列表中插入一条新的事件void printevlist();/打印事件列表/*/*计时器模块*void stoptimer(int);/停止计时器void starttimer(int,float);/启动计时器/*/*网络各层之间传送模块*void tolayer3(int AorB,struct pkt packet);/向第3层发送信息void tolayer5(int AorB,char datasent20);/向第5层发送信息二
8、、 GBN.c#include GBN.h#include #include #include extern int TRACE = 1; /* for my debugging */为我的调试extern int nsim = 0; /* number of messages from 5 to 4 so far */目前为止信息的数字是从5到4extern int nsimmax = 0; /* number of msgs to generate, then stop */如果信息产生的数字为0,然后就停止extern float time = 0.000;float lossprob;
9、 /* probability that a packet is dropped */数据包可能会丢失float corruptprob; /* probability that one bit is packet is flipped */这一点的数据包可能会被弹出去float lambda; /* arrival rate of messages from layer 5 */ 第五层到达的信息的次序int ntolayer3; /* number sent into layer 3 */被传送到第三层的数据static int nlost = 0; /* number lost in m
10、edia */在媒介中数据丢失staticintncorrupt=0;/*numbercorruptedbymedia*/被媒介毁坏的数据staticintexpectedseqnum=0;/*expectedsequencenumberatreceiverside*/在接收者这边接收到预期的序列数据staticintnextseqnum;/*nextsequencenumbertouseinsenderside*/下一个序列数据使用在发送者这边staticintbase;/*theheadofsenderwindow*/发送者的头窗口structpktwinbufWINDOWSIZE;/*w
11、indowpacketsbuffer*/数据包缓冲区窗口staticintwinfront,winrear;/*frontandrearpointsofwindowbuffer*/窗口缓冲区的前方点和后方点staticintpktnum;/*packetnumberofwindowbuffer*/窗口缓冲区的数据包个数structmsgbufferMAXBUFSIZE;/*sendermessagebuffer*/发送消息缓冲区intbuffront,bufrear;/*frontandrearpointersofbuffer*/缓冲区的前指针与后指针staticintmsgnum;/*mes
12、sagenumberofbuffer*/信息数量的缓冲int packet_lost =0; int packet_corrupt=0;int packet_sent =0;extern int packet_correct=0;extern int packet_resent =0;int packet_timeout=0;extern struct event *evlist = NULL; /* the event list */计算校验和void ComputeChecksum( struct pkt *packet) int checksum; int i; checksum = p
13、acket-seqnum; checksum = checksum + packet-acknum; for ( i=0; ipayloadi); checksum = 0-checksum; packet-checksum = checksum;/检查是否出错int CheckCorrupted(struct pkt packet) int checksum; int i; checksum = packet.seqnum; checksum = checksum + packet.acknum; for ( i=0; i20; i+ ) checksum = checksum + (int
14、)(packet.payloadi); if ( (packet.checksum+checksum) = 0 ) return (FALSE); else return (TRUE);/A端向外发送数据/* called from layer 5, passed the data to be sent to other side */void A_output(struct msg message) int i; struct pkt sendpkt; /* if window is not full */ if ( nextseqnum base+WINDOWSIZE ) printf(-
15、A: New message arrives, send window is not full, send new messge to layer3!n); /* create packet */ sendpkt.seqnum = nextseqnum; sendpkt.acknum = NOTUSED; for ( i=0; i20 ; i+ ) sendpkt.payloadi = message.datai; /* computer checksum */ ComputeChecksum (&sendpkt); /* send out packet */ tolayer3 (A, sen
16、dpkt); /* copy the packet to window packet buffer */ winrear = (winrear+1)%WINDOWSIZE; pktnum +; winbufwinrear = sendpkt; for (i=0; i20; i+) winbufwinrear.payloadi= sendpkt.payloadi; /* update state variables */ nextseqnum = nextseqnum+1; starttimer(A,RTT); B_input(sendpkt); A_input(sendpkt); /* if
17、window is full */ else printf(-A: New message arrives, send window is full,); /* if buffer full, give up and exit*/ if ( msgnum = MAXBUFSIZE) printf ( Error: Sender buffer is full! n); exit (1); /* otherwise, buffer the message */ else printf(buffer new message!n); bufrear = (bufrear+1) % MAXBUFSIZE
18、; for (i=0; i20; i+) bufferbufrear.datai = message.datai; msgnum +; /B端向外发送数据/* called from layer 5, passed the data to be sent to other side */void B_output(struct msg message) int i; struct pkt sendpkt; /* if window is not full */ if ( nextseqnum base+WINDOWSIZE ) printf(-A: New message arrives, s
19、end window is not full, send new messge to layer3!n); /* create packet */ sendpkt.seqnum = nextseqnum; sendpkt.acknum = NOTUSED; for ( i=0; i20 ; i+ ) sendpkt.payloadi = message.datai; /* computer checksum */ ComputeChecksum (&sendpkt); /* send out packet */ tolayer3 (A, sendpkt); A_input(sendpkt);
20、/* copy the packet to window packet buffer */ winrear = (winrear+1)%WINDOWSIZE; pktnum +; winbufwinrear = sendpkt; for (i=0; i20; i+) winbufwinrear.payloadi= sendpkt.payloadi; /* if it is the first packet in window, start timeout */ /if ( base = nextseqnum ) / /starttimer(A,RTT); /printf(-A: start a
21、 new timer!n); / /* update state variables */ nextseqnum = nextseqnum+1; /* if window is full */ else printf(-A: New message arrives, send window is full,); /* if buffer full, give up and exit*/ if ( msgnum = MAXBUFSIZE) printf ( Error: Sender buffer is full! n); exit (1); /* otherwise, buffer the m
22、essage */ else printf(buffer new message!n); bufrear = (bufrear+1) % MAXBUFSIZE; for (i=0; i20; i+) bufferbufrear.datai = message.datai; msgnum +; /A端接收数据void A_input(struct pkt packet) struct pkt sendpkt; int i; /* if received packet is not corrupted and ACK is received */ if ( (CheckCorrupted(pack
23、et) = FALSE) & (packet.acknum != NACK) ) printf(-A: ACK %d is correctly received,packet.acknum); packet_correct+; /* delete the acked packets from window buffer */ winfront = (winfront+(packet.acknum+1-base) % WINDOWSIZE; pktnum = pktnum - (packet.acknum+1-base); /* move window base */ base = packet
24、.acknum+1; stoptimer(A); if ( base nextseqnum) /starttimer(A,RTT); printf (nnnsend new packets!); /* if buffer is not empty, send new packets */ while ( (msgnum!=0) & (nextseqnumbase+WINDOWSIZE) ) /* create packet */ sendpkt.seqnum = nextseqnum; sendpkt.acknum = NOTUSED; buffront = (buffront+1) % MA
25、XBUFSIZE; for ( i=0; i20 ; i+ ) sendpkt.payloadi = bufferbuffront.datai; /* computer checksum */ ComputeChecksum (&sendpkt); /* if it is the first packet in window, start timeout */ if ( base = nextseqnum ) /starttimer(A,RTT); printf (send new packets!n); /* send out packet */ tolayer3 (A, sendpkt); /* copy the packet to window packet buffer */ winrear = (winrear+1)%WINDOWSIZE; winbufwinrear = sendpkt; pktnum +; /* update state variables */ nextseqnum = nextseqnum+1; /* delete messa
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1