云南大学 软件学院 计网实验5 - 图文
更新时间:2024-04-10 16:46:01 阅读量: 综合文库 文档下载
- 云南大学附属医院推荐度:
- 相关推荐
云南大学软件学院 实 验 报 告
课程: 计算机网络原理实验 任课教师:
姓名: 学号: 专业: 成绩:
实验五、传输层可靠传输协议GBN编程实验报告
一、实验目的:
1、编程实现简单可靠的数据传输GBN协议,模拟可靠数据传输
2、理解TCP协议可靠传输的差错检测、重传、累计确认、定时器的可靠传输策略。
二、实验指导:
参考教材。
三、实验要求:
编程实现一个GBN传输协议,采用编程语言不限,要求能将发送――接收流程以及处理方法表现出来.附源代码及注释并附上实验结果截图。 #include
/* ****************************************************************** ALTERNATING BIT AND GO-BACK-N NETWORK EMULATOR: VERSION 1.1 J.F.Kurose
This code should be used for PA2, unidirectional or bidirectional data transfer protocols (from A to B. Bidirectional transfer of data is for extra credit and is not required). Network properties: - one way network delay averages five time units (longer if there are other messages in the channel for GBN), but can be larger - packets can be corrupted (either the header or the data portion) or lost, according to user-defined probabilities
- packets will be delivered in the order in which they were sent (although some can be lost).
**********************************************************************/
#define BIDIRECTIONAL 0 /* change to 1 if you're doing extra credit */ /* and write a routine called B_output */
/* a \/* 4 (students' code). It contains the data (characters) to be delivered */ /* to layer 5 via the students transport level protocol entities. */ struct msg { char data[20];
};
/* 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 payload[20]; };
/********* STUDENTS WRITE THE NEXT SEVEN ROUTINES *********/
#define WINDOWSIZE 8 #define MAXBUFSIZE 50 定义基本常量参数 #define RTT 15.0
#define NOTUSED 0 #define NACK -1
#define TRUE 1 #define FALSE 0
#define A 0 #define B 1
int expectedseqnum; /* expected sequence number at receiver side */
int nextseqnum; /* next sequence number to use in sender side */ int base; /* the head of sender window */
struct pkt winbuf[WINDOWSIZE]; /* window packets buffer */
int winfront,winrear; /* front and rear points of window buffer */ int pktnum; /* packet number of window buffer */
struct msg buffer[MAXBUFSIZE]; /* sender message buffer */
int buffront,bufrear; /* front and rear pointers of buffer */ int msgnum; /* message number of buffer */
int packet_lost =0; int packet_corrupt=0; int packet_sent =0;
int packet_correct=0; int packet_resent =0; int packet_timeout=0;
void ComputeChecksum(packet) struct pkt *packet; { 定义一个包(按照课本要 int checksum; 求定义基本的内容,包括 int i; 校验码、序号以及确认信 号等基本信息)。 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; }
int CheckCorrupted(packet) 对包的检查的函 struct pkt packet;
数。 {
int checksum; int i;
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); }
/* called from layer 5, passed the data to be sent to other side */ A_output(message) struct msg message; { A端发出数据包 int i;
struct pkt sendpkt;
/* if window is not full */
if ( nextseqnum < base+WINDOWSIZE ) {
printf(\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; i<20 ; i++ )
sendpkt.payload[i] = message.data[i];
/* computer checksum */
ComputeChecksum (&sendpkt);
/* send out packet */ tolayer3 (A, sendpkt);
/* copy the packet to window packet buffer */ winrear = (winrear+1)%WINDOWSIZE; pktnum ++;
winbuf[winrear] = sendpkt; for (i=0; i<20; i++)
winbuf[winrear].payload[i]= sendpkt.payload[i];
/* if it is the first packet in window, start timeout */ if ( base == nextseqnum ) { starttimer(A,RTT);
printf(\ }
/* update state variables */ nextseqnum = nextseqnum+1; }
/* if window is full */ else {
printf(\ /* if buffer full, give up and exit*/ if ( msgnum == MAXBUFSIZE) {
printf (\ exit (1); }
/* otherwise, buffer the message */ else {
printf(\
bufrear = (bufrear+1) % MAXBUFSIZE; for (i=0; i<20; i++)
buffer[bufrear].data[i] = message.data[i]; msgnum ++; } }
B端输出数据包。 }
B_output(message) /* need be completed only for extra credit */ struct msg message; { }
/* called from layer 3, when a packet arrives for layer 4 */ A_input(packet)
struct pkt packet; {
数据包进入A端并进行处理,例如像对 struct pkt sendpkt; 校验码的处理以及对计时器的处理。 int i;
/* if received packet is not corrupted and ACK is received */
if ( (CheckCorrupted(packet) == FALSE) && (packet.acknum != NACK) ) { printf(\
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.acknum+1;
stoptimer(A);
if ( base < nextseqnum) { starttimer(A,RTT);
printf (\ }
/* if buffer is not empty, send new packets */
while ( (msgnum!=0) && (nextseqnum
sendpkt.seqnum = nextseqnum; sendpkt.acknum = NOTUSED;
buffront = (buffront+1) % MAXBUFSIZE; for ( i=0; i<20 ; i++ )
sendpkt.payload[i] = buffer[buffront].data[i]; /* computer checksum */
ComputeChecksum (&sendpkt);
/* if it is the first packet in window, start timeout */ if ( base == nextseqnum ){ starttimer(A,RTT);
printf (\ }
/* send out packet */ tolayer3 (A, sendpkt);
/* copy the packet to window packet buffer */ winrear = (winrear+1)%WINDOWSIZE; winbuf[winrear] = sendpkt; pktnum ++;
/* update state variables */
nextseqnum = nextseqnum+1; /* delete message from buffer */ msgnum --; } } else
printf (\}
/* called when A's timer goes off */ A_timerinterrupt() { A端计时器的处理过程 int i;
printf(\ /* start timer */ starttimer(A,RTT);
/* resend all packets not acked */ for ( i=1; i<=pktnum; i++ ) {
packet_resent++;
tolayer3(A,winbuf[(winfront+i)%WINDOWSIZE]); }
}
/* the following routine will be called once (only) before any other */ /* entity A routines are called. You can use it to do any initialization */ A_init() {
A端初始化。 base = 0; nextseqnum = 0; buffront = 0; bufrear = 0; msgnum = 0; winfront = 0; winrear = 0; pktnum = 0; }
/* Note that with simplex transfer from a-to-B, there is no B_output() */
/* called from layer 3, when a packet arrives for layer 4 at B*/ B_input(packet)
struct pkt packet; {
B包的构建过程。 struct pkt sendpkt; int i;
/* if not corrupted and received packet is in order */
if ( (CheckCorrupted(packet) == FALSE) && (packet.seqnum == expectedseqnum)){ printf(\packet %d is correctly received, send ACK!\\n\
/* send an ACK for the received packet */ /* create packet */
sendpkt.seqnum = NOTUSED;
sendpkt.acknum = expectedseqnum; for ( i=0; i<20 ; i++ )
sendpkt.payload[i] = '0'; /* computer checksum */
ComputeChecksum (&sendpkt); /* send out packet */ tolayer3 (B, sendpkt);
/* update state variables */
expectedseqnum = expectedseqnum+1;
/* deliver received packet to layer 5 */ tolayer5(B,packet.payload); }
/* otherwise, discard the packet and send a NACK */ else {
printf(\packet %d is corrupted or not I expects, send NACK!\\n\ /* create packet */
sendpkt.seqnum = NOTUSED; sendpkt.acknum = NACK; for ( i=0; i<20 ; i++ )
sendpkt.payload[i] = '0'; /* computer checksum */
ComputeChecksum (&sendpkt); /* send out packet */ tolayer3 (B, sendpkt); } }
/* called when B's timer goes off */ B_timerinterrupt() {
B端计时器 }
以及B端的初始化
/* the following rouytine will be called once (only) before any other */ /* entity B routines are called. You can use it to do any initialization */ B_init() {
expectedseqnum = 0; }
/***************************************************************** ***************** NETWORK EMULATION CODE STARTS BELOW *********** The code below emulates the layer 3 and below network environment:
- emulates the tranmission and delivery (possibly with bit-level corruption and packet loss) of packets across the layer 3/4 interface - handles the starting/stopping of a timer, and generates timer interrupts (resulting in calling students timer handler). - generates message to be sent (passed from later 5 to 4)
THERE IS NOT REASON THAT ANY STUDENT SHOULD HAVE TO READ OR UNDERSTAND THE CODE BELOW. YOU SHOLD NOT TOUCH, OR REFERENCE (in your code) ANY OF THE DATA STRUCTURES BELOW. If you're interested in how I designed
the emulator, you're welcome to look at the code - but again, you should have to, and you defeinitely should not have to modify
******************************************************************/ 定义仿真部分event事件结构体: 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) assoc w/ this event */ struct event *prev; struct event *next; };
struct event *evlist = NULL; /* the event list */
/* possible events: */
#define TIMER_INTERRUPT 0 #define FROM_LAYER5 1 #define FROM_LAYER3 2
#define OFF 0 #define ON 1 #define A 0 #define B 1
int TRACE = 1; /* for my debugging */
int nsim = 0; /* number of messages from 5 to 4 so far */ int nsimmax = 0; /* number of msgs to generate, then stop */ float time = 0.000;
float lossprob; /* 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 */ int nlost; /* number lost in media */ int ncorrupt; /* number corrupted by media*/
main() { 该处是主函数,进 struct event *eventptr; 行输出到dos窗 struct msg msg2give; 口的运行部分,这 struct pkt pkt2give; 里用于调用其它 函数来实现GBN int i,j; 函数的功能。 char c;
init(); A_init(); B_init();
while (1) {
eventptr = evlist; /* get next event to simulate */ if (eventptr==NULL) goto terminate;
evlist = evlist->next; /* remove this event from event list */ if (evlist!=NULL)
evlist->prev=NULL; if (TRACE>=2) {
printf(\ printf(\ if (eventptr->evtype==0)
printf(\ else if (eventptr->evtype==1) printf(\ else
printf(\
printf(\ }
time = eventptr->evtime; /* update time to next event time */ if (nsim==nsimmax)
break; /* all done with simulation */ if (eventptr->evtype == FROM_LAYER5 ) {
generate_next_arrival(); /* set up future arrival */ /* fill in msg to give with string of same letter */ j = nsim % 26;
for (i=0; i<20; i++)
msg2give.data[i] = 97 + j; if (TRACE>2) {
printf(\ for (i=0; i<20; i++)
printf(\ printf(\ }
nsim++;
if (eventptr->eventity == A) A_output(msg2give); else
B_output(msg2give); }
else if (eventptr->evtype == FROM_LAYER3) {
pkt2give.seqnum = eventptr->pktptr->seqnum; pkt2give.acknum = eventptr->pktptr->acknum; pkt2give.checksum = eventptr->pktptr->checksum; for (i=0; i<20; i++)
pkt2give.payload[i] = eventptr->pktptr->payload[i];
if (eventptr->eventity ==A) /* deliver packet by calling */ A_input(pkt2give); /* appropriate entity */ else
B_input(pkt2give);
free(eventptr->pktptr); /* free the memory for packet */ }
else if (eventptr->evtype == TIMER_INTERRUPT) {
if (eventptr->eventity == A) A_timerinterrupt(); else
B_timerinterrupt(); }
else {
printf(\ }
free(eventptr); }
terminate:
printf(\Simulator terminated at time %f\\n after sending %d msgs from layer5\\n\
printf(\ printf(\ }
init() /* initialize the simulator */ {
int i;
float sum, avg; float jimsrand();
对文件的处理函数的初始
化。 FILE *fp;
fp = fopen (\
printf(\ printf(\ fscanf(fp,\ scanf(\
printf(\ fscanf(fp, \ scanf(\
printf(\ fscanf(fp,\ scanf(\
printf(\ fscanf(fp,\ scanf(\ printf(\ fscanf(fp,\ scanf(\
srand(9999); /* init random number generator */
sum = 0.0; /* test random number generator for students */ for (i=0; i<1000; i++)
sum=sum+jimsrand(); /* jimsrand() should be uniform in [0,1] */ avg = sum/1000.0;
if (avg < 0.25 || avg > 0.75) {
printf(\ printf(\ printf(\ exit(1); }
ntolayer3 = 0; nlost = 0; ncorrupt = 0;
time=0.0; /* initialize time to 0.0 */ generate_next_arrival(); /* initialize event list */
}
/****************************************************************************/ /* jimsrand(): return a float in range [0,1]. The routine below is used to */ /* isolate all random number generation in one location. We assume that the*/ /* system-supplied rand() function return an int in therange [0,mmm] */ /****************************************************************************/ float jimsrand() {
double mmm = 65535; /* largest int 2147483647 65535 - MACHINE DEPENDENT!!!!!!!! */
float x; /* individual students may need to change mmm */ x = rand()/mmm; /* x should be uniform in [0,1] */ return(x); }
/********************* EVENT HANDLINE ROUTINES ****2147483647***/ /* The next set of routines handle the event list */ /*****************************************************/
generate_next_arrival() {
double x,log(),ceil();
对下一条消息到来后的处理 struct event *evptr;
事件。 char *malloc();
float ttime; int tempint;
if (TRACE>2)
printf(\
x = lambda*jimsrand()*2; /* x is uniform on [0,2*lambda] */ /* having mean of lambda */ evptr = (struct event *)malloc(sizeof(struct event)); evptr->evtime = time + x; evptr->evtype = FROM_LAYER5;
if (BIDIRECTIONAL && (jimsrand()>0.5) ) evptr->eventity = B; else
evptr->eventity = A; insertevent(evptr); } 向事件列表中插入一条新 的事件 insertevent(p)
struct event *p; {
struct event *q,*qold;
if (TRACE>2) {
printf(\
printf(\ }
q = evlist; /* q points to front of list in which p struct inserted */ if (q==NULL)
{ /* list is empty */ evlist=p; p->next=NULL; p->prev=NULL; } else {
for (qold = q; q !=NULL && p->evtime > q->evtime; q=q->next) qold=q; if (q==NULL)
{ /* end of list */ qold->next = p; p->prev = qold; p->next = NULL; }
else if (q==evlist) { /* front of list */ p->next=evlist; p->prev=NULL; p->next->prev=p; evlist = p; } else
{ /* middle of list */ p->next=q;
p->prev=q->prev; q->prev->next=p; q->prev=p; } } } 打印事件列表 printevlist() {
struct event *q; int i;
printf(\ for(q = evlist; q!=NULL; q=q->next) { printf(\time: %f, type: %d entity: %d\\n\ }
printf(\}
停止计时器
/********************** Student-callable ROUTINES ***********************/
/* called by students routine to cancel a previously-started timer */ stoptimer(AorB) int AorB; /* A or B is trying to stop timer */ {
struct event *q,*qold;
if (TRACE>2)
printf(\/* for (q=evlist; q!=NULL && q->next!=NULL; q = q->next) */ for (q=evlist; q!=NULL ; q = q->next)
if ( (q->evtype==TIMER_INTERRUPT && q->eventity==AorB) ) { /* remove this event */
if (q->next==NULL && q->prev==NULL)
evlist=NULL; /* remove first and only event on list */ else if (q->next==NULL) /* end of list - there is one in front */ q->prev->next = NULL;
else if (q==evlist) { /* front of list - there must be event after */ q->next->prev=NULL; evlist = q->next; }
else { /* middle of list */ q->next->prev = q->prev; q->prev->next = q->next; } free(q); return; }
printf(\
正在阅读:
云南大学 软件学院 计网实验5 - 图文04-10
英语专业毕业论文09-19
我真后悔作文500字07-04
推荐下载 在市纪律检查委员会第四次全体会议上的讲话-最新(3)12-17
微观经济学习题集11-23
网上购物系统的设计与实现 论文 - 图文01-21
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 云南大学
- 软件学院
- 实验
- 图文
- 一通三防专业技术人员复习题库1
- 百格子练习(20以内加法)
- 中山大学信息光学习题课后答案--习题234章作业
- 江苏省高邮市八桥镇初级中学八年级物理上册 第一章《声现象》二
- XX办公用品公司营销方案 - 图文
- 优秀学生先进事迹材料
- 心中的一盏灯 - 浅谈我的高中生活与学习(高考学习 励志文章)
- 校本课程东平历史人物 - - --活动设计
- 通信原理实验报告2
- 论四川地区外墙内保温技术体系优于外墙外保温技术体系 - 图文
- PPAP培训试题(答案)
- 2014浙江高考真题生物(含解析)
- 副镇长民主生活会
- 腹腔镜中低位直肠癌根治术临床可行性开题 文档
- 信江(信州区-上饶县段)饮用水源保护区划分方案 - 图文
- 施工组织方案
- 利川市2007-2008学年度第一学期期未调研考试小学三年级
- 广联达软件操作总结
- 2015春东北财经大学《特殊会计准则》在线作业二满分答案
- 电子科普知识竞赛策划书1