计算机网络原理实验五.docx
- 文档编号:24686583
- 上传时间:2023-05-31
- 格式:DOCX
- 页数:37
- 大小:104.39KB
计算机网络原理实验五.docx
《计算机网络原理实验五.docx》由会员分享,可在线阅读,更多相关《计算机网络原理实验五.docx(37页珍藏版)》请在冰豆网上搜索。
计算机网络原理实验五
实验五、传输层可靠传输协议GBN编程实验报告
序号:
姓名:
学号:
成绩:
一、实验目的:
1、编程实现简单可靠的数据传输GBN协议,模拟可靠数据传输
2、理解TCP协议可靠传输的差错检测、重传、累计确认、定时器的可靠传输策略。
二、实验指导:
参考教材。
三、实验要求:
编程实现一个GBN传输协议,采用编程语言不限,要求能将发送――接收流程以及处理方法表现出来.附源代码及注释并附上实验结果截图。
一、GBN.h
#pragmaonce
#include
//基础功能模块的数据结构声明
#defineBIDIRECTIONAL1/*changeto1ifyou'redoingextracreditandwritearoutinecalledB_output*/如果你想做酷文解码和写一个程序叫B_output就改变值为1
/*a"msg"isthedataunitpassedfromlayer5(teacherscode)tolayer4(students'code).Itcontainsthedata(characters)tobedeliveredtolayer5viathestudentstransportlevelprotocolentities.*/
一个“msg”是从第五层传送到第四层的数据单元.它包含通过传送层协议被传送到第五层的数据
structmsg
{chardata[20];
};
/*apacketisthedataunitpassedfromlayer4(studentscode)tolayer3(teacherscode).Notethepre-definedpacketstructure,whichall
studentsmustfollow.*/一个数据包从第四层传送到第三层的数据单元.声明提前定义的学生必须遵守的数据包结构
structpkt
{
intseqnum;
intacknum;
intchecksum;
charpayload[20];
};
#defineWINDOWSIZE8
#defineMAXBUFSIZE50
#defineRTT15.0
#defineNOTUSED0
#defineNACK-1
#defineTRUE1
#defineFALSE0
#defineA0
#defineB1
//网络仿真部分数据结构声明***********************************************************
structevent
{
floatevtime;/*eventtime*/事件时间
intevtype;/*eventtypecode*/事件类型代码
inteventity;/*entitywhereeventoccurs*/所在的实体事件
发生时
structpkt*pktptr;/*ptrtopacket(ifany)assocw/thisevent*/用指针来显示这个数据包
structevent*prev;
structevent*next;
};
/*possibleevents:
*/可能发生
#defineTIMER_INTERRUPT0
#defineFROM_LAYER51
#defineFROM_LAYER32
#defineOFF0
#defineON1
//基础功能模块的函数声明*******************************************************************
voidComputeChecksum(structpkt*packet);//计算校验和
intCheckCorrupted(structpktpacket);//检查数据是否出错
voidA_output(structmsgmessage);//A端向外发送数据
voidA_input(structpktpacket);//A端接收数据
voidA_timerinterrupt();//A计时器超时
voidA_init();//A端初始化
voidB_output(structmsgmessage);
voidB_input(structpktpacket);
voidB_timerinterrupt();
voidB_init();
//网络仿真部分的函数声明**************************************************
voidinit();//初始化仿真器
floatjimsrand();//随机数发生器[0,1]
//处理事件列表部分的函数声明*********************************************
voidgenerate_next_arrival();//产生下一个到达的分组
voidinsertevent(structevent*p);//向事件列表中插入一条新的事件
voidprintevlist();//打印事件列表
//********************************************************************
//**********************计时器模块***********************************
voidstoptimer(int);//停止计时器
voidstarttimer(int,float);//启动计时器
//*********************************************************************
//**************************网络各层之间传送模块***********************
voidtolayer3(intAorB,structpktpacket);//向第3层发送信息
voidtolayer5(intAorB,chardatasent[20]);//向第5层发送信息
二、GBN.c
#include"GBN.h"
#include
#include
#include
externintTRACE=1;/*formydebugging*/为我的调试
externintnsim=0;/*numberofmessagesfrom5to4sofar*/目前为止信息的数字是从5到4
externintnsimmax=0;/*numberofmsgstogenerate,thenstop*/如果信息产生的数字为0,然后就停止
externfloattime=0.000;
floatlossprob;/*probabilitythatapacketisdropped*/数据包可能会丢失
floatcorruptprob;/*probabilitythatonebitispacketisflipped*/这一点的数据包可能会被弹出去
floatlambda;/*arrivalrateofmessagesfromlayer5*/从
第五层到达的信息的次序
intntolayer3;/*numbersentintolayer3*/被传送到第三层的数据
staticintnlost=0;/*numberlostinmedia*/在媒介中数据丢失
staticintncorrupt=0;/*numbercorruptedbymedia*/
被媒介毁坏的数据
staticintexpectedseqnum=0;/*expectedsequencenumberatreceiverside*/在接收者这边接收到预期的序列数据
staticintnextseqnum;/*nextsequencenumbertouseinsenderside*/下一个序列数据使用在发送者这边
staticintbase;/*theheadofsenderwindow*/
发送者的头窗口
structpktwinbuf[WINDOWSIZE];/*windowpacketsbuffer*/
数据包缓冲区窗口
staticintwinfront,winrear;/*frontandrearpointsofwindowbuffer*/
窗口缓冲区的前方点和后方点
staticintpktnum;/*packetnumberofwindowbuffer*/
窗口缓冲区的数据包个数
structmsgbuffer[MAXBUFSIZE];/*sendermessagebuffer*/
发送消息缓冲区
intbuffront,bufrear;/*frontandrearpointersofbuffer*/
缓冲区的前指针与后指针
staticintmsgnum;/*messagenumberofbuffer*/
信息数量的缓冲
intpacket_lost=0;
intpacket_corrupt=0;
intpacket_sent=0;
externintpacket_correct=0;
externintpacket_resent=0;
intpacket_timeout=0;
externstructevent*evlist=NULL;/*theeventlist*/事件表
//计算校验和
voidComputeChecksum(structpkt*packet)
{
intchecksum;
inti;
checksum=packet->seqnum;
checksum=checksum+packet->acknum;
for(i=0;i<20;i++)
checksum=checksum+(int)(packet->payload[i]);
checksum=0-checksum;
packet->checksum=checksum;
}
//检查是否出错
intCheckCorrupted(structpktpacket)
{
intchecksum;
inti;
checksum=packet.seqnum;
checksum=checksum+packet.acknum;
for(i=0;i<20;i++)
checksum=checksum+(int)(packet.payload[i]);
if((packet.checksum+checksum)==0)
return(FALSE);
else
return(TRUE);
}
//A端向外发送数据
/*calledfromlayer5,passedthedatatobesenttootherside*/
来自第五层,通过数据派往另一边
voidA_output(structmsgmessage)
{
inti;
structpktsendpkt;
/*ifwindowisnotfull*/如果窗口没有满
if(nextseqnum
{
printf("----A:
Newmessagearrives,sendwindowisnotfull,sendnewmessgetolayer3!
\n");
/*createpacket*/创建包
sendpkt.seqnum=nextseqnum;
sendpkt.acknum=NOTUSED;
for(i=0;i<20;i++)
sendpkt.payload[i]=message.data[i];
/*computerchecksum*/计算机校验
ComputeChecksum(&sendpkt);
/*sendoutpacket*/发送数据包
tolayer3(A,sendpkt);
/*copythepackettowindowpacketbuffer*/复制数据包到窗口数据缓冲区
winrear=(winrear+1)%WINDOWSIZE;
pktnum++;
winbuf[winrear]=sendpkt;
for(i=0;i<20;i++)
winbuf[winrear].payload[i]=sendpkt.payload[i];
/*updatestatevariables*/更新状态变量
nextseqnum=nextseqnum+1;
starttimer(A,RTT);
B_input(sendpkt);
A_input(sendpkt);
}
/*ifwindowisfull*/如果窗口没有满
else
{
printf("----A:
Newmessagearrives,sendwindowisfull,");
/*ifbufferfull,giveupandexit*/如果缓冲区满了,停止和退出
if(msgnum==MAXBUFSIZE)
{
printf("Error:
Senderbufferisfull!
\n");
exit
(1);
}
/*otherwise,bufferthemessage*/否则,缓冲信息
else
{
printf("buffernewmessage!
\n");
bufrear=(bufrear+1)%MAXBUFSIZE;
for(i=0;i<20;i++)
buffer[bufrear].data[i]=message.data[i];
msgnum++;
}
}
}
//B端向外发送数据
/*calledfromlayer5,passedthedatatobesenttootherside*/
来自第五层,通过数据传送到另一边
voidB_output(structmsgmessage)
{
inti;
structpktsendpkt;
/*ifwindowisnotfull*/如果窗口没有满
if(nextseqnum
{
printf("----A:
Newmessagearrives,sendwindowisnotfull,sendnewmessgetolayer3!
\n");
/*createpacket*/创建数据包
sendpkt.seqnum=nextseqnum;
sendpkt.acknum=NOTUSED;
for(i=0;i<20;i++)
sendpkt.payload[i]=message.data[i];
/*computerchecksum*/计算机校验
ComputeChecksum(&sendpkt);
/*sendoutpacket*/发送数据包
tolayer3(A,sendpkt);
A_input(sendpkt);
/*copythepackettowindowpacketbuffer*/复制数据包到窗口数据缓冲区
winrear=(winrear+1)%WINDOWSIZE;
pktnum++;
winbuf[winrear]=sendpkt;
for(i=0;i<20;i++)
winbuf[winrear].payload[i]=sendpkt.payload[i];
/*ifitisthefirstpacketinwindow,starttimeout*/
如果第一个数据包在窗口里,开始暂停
//if(base==nextseqnum)
//{
//starttimer(A,RTT);
//printf("----A:
startanewtimer!
\n");
//}
/*updatestatevariables*/更新状态变量
nextseqnum=nextseqnum+1;
}
/*ifwindowisfull*/如果窗口已经满了
else
{
printf("----A:
Newmessagearrives,sendwindowisfull,");
/*ifbufferfull,giveupandexit*/如果缓冲区满了,停止并退出
if(msgnum==MAXBUFSIZE)
{
printf("Error:
Senderbufferisfull!
\n");
exit
(1);
}
/*otherwise,bufferthemessage*/否则,缓冲信息
else
{
printf("buffernewmessage!
\n");
bufrear=(bufrear+1)%MAXBUFSIZE;
for(i=0;i<20;i++)
buffer[bufrear].data[i]=message.data[i];
msgnum++;
}
}
}
//A端接收数据
voidA_input(structpktpacket)
{
structpktsendpkt;
inti;
/*ifreceivedpacketisnotcorruptedandACKisreceived*/
如果接收到的数据包没有被损坏和确认已经被接收了
if((CheckCorrupted(packet)==FALSE)&&(packet.acknum!
=NACK))
{
printf("----A:
ACK%discorrectlyreceived,",packet.acknum);
packet_correct++;
/*deletetheackedpacketsfromwindowbuffer*/
删除从窗口缓冲区里的确认数据包
winfront=(winfront+(packet.acknum+1-base))%WINDOWSIZE;
pktnum=pktnum-(packet.acknum+1-base);
/*movewindowbase*/移动窗口底部
base=packet.acknum+1;
stoptimer(A);
if(base { //starttimer(A,RTT); printf("\n\n\nsendnewpackets! "); } /*ifbufferisnotempty,sendnewpackets*/ 如果缓冲区不空,发送新的数据包 while((msgnum! =0)&&(nextseqnum { /*createpacket*/创建数据包 sendpkt.seqnum=nextseqnum; sendpkt.acknum=NOTUSED; buffront=(buffront+1)%MAXBUFSIZE; for(i=0;i<20;i++) sendpkt.payload[i]=buffer[buffront].data[i]; /*computerchecksum*/计算机校验 ComputeChecksum(&sendpkt); /*ifitisthefirstpacketinwindow,starttimeout*/ 如果第一个数据包在窗口里,开始暂停 if(base==nextseqnum) { //starttimer(A,RTT); printf("sendnewpackets! \n"); } /*sendoutpacket*/发送数据包 tolayer3(A,sendpkt); /*copythepackettowindowpacketbuffer*/ 复制数据包到窗口数据缓冲区 winrear=(winrear+1)%WINDOWSIZE; winbuf[winrear]=sendpkt; pktnum++; /*updatestatevariables*/更新状态变量 nextseqnum=nextseqnum+1; /*deletemessagefrombuffer*/删除缓冲区的信息 msgnum--; } } else printf("----A: NACKisreceived,donothing! \n"); } //B端接收数据*****************************************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机网络 原理 实验