版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、中文注释编程实现一个GBN传输协议的发送方和接收方两程序,采用编程语言不限,要求能将发送接收流程以及处理方法表现出来.附源代码及注释源代码:三:GBN-CS.c#include "GBN.h"#include <stdio.h>#include <string.h>#include <stdlib.h>extern int TRACE ; /* 用于跟踪 */ extern int nsim ; /* 当前第5层到第4层的信息数 */ extern int nsimmax; /*"msg"生成数量,直到停止,生成的最大
2、信息数 */extern float time; /时间extern int packet_correct; /包的正确到达数extern int packet_resent; /包的重传数extern struct event *evlist; /事件int main() /主函数struct event *eventptr;/变量,结构体声明struct msg msg2give;struct pkt pkt2give;int i,j;char c; init();/初始化 A_init();/A端初始化 B_init();/B端初始化 while (1) /循环,用于每个包的传送 eve
3、ntptr = evlist; /* 从模拟器得到下一个事件 */ if (eventptr=NULL)goto terminate; evlist = evlist->next;/* 从事件清单改变该事件 */ if (evlist!=NULL)evlist->prev=NULL;if (TRACE >= 2)/打印与事件相关的信息printf("n事件时间: %f,",eventptr->evtime);printf(" 类型: %d",eventptr->evtype);if (eventptr->evtype=
4、0)printf(", 计时器中断: ");else if (eventptr->evtype=1)printf(", 来自第五层 ");elseprintf(", 来自第三层 ");if (eventptr->eventity = A)/打印事件实体printf(" 通信实体: %d A端n",eventptr->eventity); elseprintf(" 通信实体: %d B端n",eventptr->eventity); time = eventptr->
5、evtime; /* 更新下一个事件的时间 */if (nsim=nsimmax)break; /* 当输入包个数等于生成的最大包个数,模拟器停止 */ if (eventptr->evtype = FROM_LAYER5 ) /如果事件调用来自第五层generate_next_arrival(); /* 为将来的包的到达做准备 */ /* 将相同的信息转换为字母字符串 */ j = nsim % 26; for (i=0; i<20; i+)msg2give.datai = 97 + j; if (TRACE>2)printf(" 学生发送的主要数据是: &quo
6、t;);for (i=0; i<20; i+)printf("%c", msg2give.datai);/打印信息printf("n"); nsim+;if (eventptr->eventity = A)/A端向外发送数据A_output(msg2give); else/B端向外发送数据B_output(msg2give);else if (eventptr->evtype = FROM_LAYER3)/如果事件调用来自第三层pkt2give.seqnum = eventptr->pktptr->seqnum; pkt2g
7、ive.acknum = eventptr->pktptr->acknum; pkt2give.checksum = eventptr->pktptr->checksum; for (i=0; i<20; i+) pkt2give.payloadi = eventptr->pktptr->payloadi;if (eventptr->eventity = A) /* A端交付包*/ A_input(pkt2give); /* 适当的实体*/else /* B端交付包*/B_input(pkt2give);free(eventptr->pkt
8、ptr); /* 释放包的缓存 */else if (eventptr->evtype = TIMER_INTERRUPT)/计时器中断情况if (eventptr->eventity = A) A_timerinterrupt();elseB_timerinterrupt();else /校检,防止发生不可预料事件printf("内部警告: 不可预知的事件类型! n"); free(eventptr); terminate:/终止 printf(" 模拟器停止在: %f s n ,从第五层发送了 %d个包n",time,nsim); pri
9、ntf(" 正确发送包的个数: %d n", packet_correct); printf(" 重发包的个数: %d n", packet_resent); system("pause");/暂停一GBN.h#pragma once#include <stdio.h>/基础功能模块的数据结构声明#define BIDIRECTIONAL 1 /* 改变值1如果你需要写额外的可靠程序或B输出程序(即B端系统)*/* "msg"结构体是由第五层(教师代码)转变成第四层的数据单元(学生代码)*/*它包括了经
10、由第五层向学生层协议通信实体交付的数据(字符)*/struct msg char data20;/* "pkt"结构体是第4层(学生代码)向第3层传送的数据单元(老师代码)。值得注意的是预先定义的包结构,这一切学生必须遵守。*/struct pktint seqnum;/顺序号int acknum;/应答号int checksum;/检查和char payload20;#define WINDOWSIZE 8 /定义滑动窗口大小#define MAXBUFSIZE 50/最大窗口大小#define RTT 15.0/周游时间#define NOTUSED 0/没用到#def
11、ine NACK -1/否定应答#define TRUE 1#define FALSE 0#define A 0#define B 1/网络仿真部分数据结构声明*struct eventfloat evtime; /* 事件时间 */int evtype; /* 事件类型 */int eventity; /* 事件实体*/struct pkt *pktptr; /* 指向这个事件的指针(如果需要) */struct event *prev; /前一事件struct event *next; /后一事件 ;/* possible events: */#define TIMER_INTERRUPT
12、 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( struct msg message);/A端向外发送数据void A_input(struct pkt packet);/A端接收数据void A_timerinterrupt
13、();/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/处理事件列表部分的函数声明*void generate_next_arrival();/产生下一个到达的分组void insertevent(struct event *p);/向事件列表中插入一条新的事件v
14、oid printevlist();/打印事件列表/*/*计时器模块*void stoptimer(int);/停止计时器void starttimer(int,float);/启动计时器/*/*网络各层之间传送模块*void tolayer3(int AorB,struct pkt packet);/向第3层发送信息void tolayer5(int AorB,char datasent20);/向第5层发送信息二:#include "GBN.h"#include <stdio.h>#include <string.h>#include <s
15、tdlib.h>extern int TRACE = 1; /*用于跟踪*/extern int nsim = 0; /* 当前第5层到第4层的信息数*/ extern int nsimmax = 0; /* "msg"生成数量,直到停止*/extern float time = 0.000;float lossprob; /* 丢包可能性*/float corruptprob; /* 包的数据位数丢失可能性*/float lambda; /* 从第五层到达的比率 */ int ntolayer3; /* 送往第3层的包数量*/static int nlost = 0
16、; /* 在媒体中丢失的包数量*/static int ncorrupt = 0; /* 在网络中被破坏的包*/static int expectedseqnum = 0; /* 期待接收方发送的序号 */static int nextseqnum; /* 下一次发送方要使用的包序号*/static int base; /* 发送方头窗*/struct pkt winbufWINDOWSIZE; /* 窗口包缓冲区*/static int winfront,winrear; /* 缓冲区的头尾指针*/static int pktnum;/* 缓冲窗口包的数量*/struct msg buffe
17、rMAXBUFSIZE; /* 发送方数据缓冲区*/int buffront,bufrear; /* 缓冲区的头尾指针 */static int msgnum;/* 缓冲窗口包的数量 */关于各种包的类型定义/*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 = N
18、ULL; /* 事件清单 */相关接口函数的实现/计算校验和,即脚链和1的补码和void ComputeChecksum( struct pkt *packet) int checksum;int i;checksum = packet->seqnum;checksum = checksum + packet->acknum;/求脚链for ( i=0; i<20; i+ ) /取最高位,按位相加checksum = checksum + (int)(packet->payloadi);checksum = 0-checksum;/取反packet->checks
19、um = checksum;/检查是否出错int CheckCorrupted(struct pkt packet)int checksum;int i;checksum = packet.seqnum;checksum = checksum + packet.acknum;for ( i=0; i<20; i+ ) checksum = checksum + (int)(packet.payloadi);if ( (packet.checksum+checksum) = 0 )/检查校检和是否相加为0return (FALSE);elsereturn (TRUE);/A端向外发送数据/
20、* 被第五层调用,向另一端发送数据*/void A_output(struct msg message)int i;struct pkt sendpkt;/* 如果的发送方下次使用序号小于滑动窗口的最大序号,那么补发包*/if ( nextseqnum < base+WINDOWSIZE )printf("-A:新的包到达,发送窗口不满,新的包送往第3层!n");/* 创建包 */sendpkt.seqnum = nextseqnum;sendpkt.acknum = NOTUSED;for ( i=0; i<20 ; i+ ) sendpkt.payloadi
21、 = message.datai;/* 检查是否出错 */ComputeChecksum (&sendpkt); /* 送出包 */ tolayer3 (A, sendpkt); /* 复制这些包到窗口缓冲区 */ winrear = (winrear+1)%WINDOWSIZE; pktnum +; winbufwinrear = sendpkt; for (i=0; i<20; i+) winbufwinrear.payloadi= sendpkt.payloadi; /* 更新状态变量 */ nextseqnum = nextseqnum+1; starttimer(A,R
22、TT); B_input(sendpkt); A_input(sendpkt);/* 如果移动窗口包满*/else printf("-A:新的包到达,发送窗口已满!");/* 如果缓冲区满,放弃并退出*/if ( msgnum = MAXBUFSIZE)printf (" 错误:发送缓冲区已满 !n"); exit (1); /* 否则,将信息送入缓冲区 */ else printf("信息已送入缓冲区n"); bufrear = (bufrear+1) % MAXBUFSIZE; /拥塞控制,防止拥塞,减小缓冲区 for (i=0;
23、 i<20; i+) bufferbufrear.datai = message.datai; msgnum +; /B端向外发送数据/* 被第五层调用,发送数据到另一方,同A方相似 */void B_output(struct msg message)int i;struct pkt sendpkt;/* 如果发送窗口不满*/if ( nextseqnum < base+WINDOWSIZE )printf("-B:新的包到达,发送窗口不满,新的包送往第3层!!n");/* create packet */sendpkt.seqnum = nextseqnum
24、;sendpkt.acknum = NOTUSED;for ( i=0; i<20 ; i+ ) sendpkt.payloadi = message.datai;/* computer checksum */ComputeChecksum (&sendpkt); /* send out packet */ tolayer3 (A, sendpkt);A_input(sendpkt); /* copy the packet to window packet buffer */ winrear = (winrear+1)%WINDOWSIZE; pktnum +; winbufwi
25、nrear = sendpkt; for (i=0; i<20; 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 new timer!n"); / /* update state variables */ nextseqnum = nextseqnum+1;/* 如果发送窗口满
26、*/else printf("-B:新的包到达,发送窗口已满!,");/* if buffer full, give up and exit*/if ( msgnum = MAXBUFSIZE)printf (" 错误:发送缓冲区已满 ! n"); exit (1); /* otherwise, buffer the message */ else printf("缓冲区满!n"); bufrear = (bufrear+1) % MAXBUFSIZE; for (i=0; i<20; i+) bufferbufrear.dat
27、ai = message.datai; msgnum +; /A端接收数据void A_input(struct pkt packet)struct pkt sendpkt;int i;/* 如果收到没有被破坏的包并且确认包收到*/ if ( (CheckCorrupted(packet) = FALSE) && (packet.acknum != NACK) )printf("-A: ACK(确认包) %d 被正确的收到,",packet.acknum);packet_correct+; /* 从窗口缓冲区删去被确认的包*/ winfront = (win
28、front+(packet.acknum+1-base) % WINDOWSIZE; pktnum = pktnum - (packet.acknum+1-base); /* 改变窗口最小号确认包 */ base = packet.acknum+1; stoptimer(A); if ( base < nextseqnum) /starttimer(A,RTT); printf ("nnn发送新的包!"); /* 如果缓冲区不空发送新的包*/ while ( (msgnum!=0) && (nextseqnum<base+WINDOWSIZE)
29、)/* 创建包*/ sendpkt.seqnum = nextseqnum; sendpkt.acknum = NOTUSED; buffront = (buffront+1) % MAXBUFSIZE; for ( i=0; i<20 ; i+ ) sendpkt.payloadi = bufferbuffront.datai; /* 和确认*/ ComputeChecksum (&sendpkt); /*如果是滑动窗口的第一个包,开始超时检测*/ if ( base = nextseqnum ) /如果滑动窗口最小的包等于下一次要发送的序号/starttimer(A,RTT)
30、;printf ("发送新的包!n"); /* 送出包 */ tolayer3 (A, sendpkt); /* 复制包到窗口缓冲区 */ winrear = (winrear+1)%WINDOWSIZE; winbufwinrear = sendpkt; pktnum +; /* 更新状态变量 */nextseqnum = nextseqnum+1; /* 删除缓冲区的包 */msgnum -;else printf ("-A: 收到否定应答,什么也没有完成!n");/B端接收数据*一定要调用这个/* 这只是单一的A到B的传送方式,没有B端的数据发出
31、*/* 被第三层调用,但数据到达B端第4层*/void B_input(struct pkt packet) struct pkt sendpkt;int i;/*如果收到没有被破坏的包并且确认包收到 */if ( (CheckCorrupted(packet) = FALSE) && (packet.seqnum = expectedseqnum)printf("n-B: 包正确的到达,发送ACK确认包n",packet.seqnum);/* 发送应答包 */ /* create packet */ sendpkt.seqnum = NOTUSED; se
32、ndpkt.acknum = expectedseqnum; for ( i=0; i<20 ; i+ )sendpkt.payloadi = '0'/* computer checksum */ ComputeChecksum (&sendpkt); /* send out packet */tolayer3 (B, sendpkt);/* update state variables */expectedseqnum = expectedseqnum+1; printf("-B:expectedseqnum (期待下一次的发送序号)= %dn&quo
33、t;,expectedseqnum); /* 发送包到第五层 */ /tolayer5(B,packet.payload); /* 否则,抛弃包,发送否定应答*/ elseprintf("-B: 包 %d 损坏或者不是我所需要的, 发送否定应答!n",packet.seqnum);/* 创建包 */ sendpkt.seqnum = NOTUSED; sendpkt.acknum = NACK; for ( i=0; i<20 ; i+ ) sendpkt.payloadi = '0'/* 校检和检查 */ ComputeChecksum (&
34、sendpkt); /* 发出包 */ tolayer3 (B, sendpkt); /A计时器超时/* A超时被调用 */void A_timerinterrupt()int i;printf("-A:超时!重新发包!n");/* start timer */starttimer(A,RTT);/* 重新发送所有未被确认的包*/for ( i=1; i<=pktnum; i+ )packet_resent+; tolayer3(A,winbuf(winfront+i)%WINDOWSIZE); /B计时器超时/* called when B's timer
35、goes off */void B_timerinterrupt()int i;printf("-B: 超时!重新发包!n");/* start timer */starttimer(B,RTT);/* 重新发送所有未被确认的包 */for ( i=1; i<=pktnum; i+ )packet_resent+; tolayer3(B,winbuf(winfront+i)%WINDOWSIZE); /A端初始化/* entity A routines are called. You can use it to do any initialization */void
36、 A_init()base = 0;nextseqnum = 0;buffront = 0;bufrear = 0;msgnum = 0;winfront = 0;winrear = 0;pktnum = 0;/B端初始化/* entity B routines are called. You can use it to do any initialization */void B_init()expectedseqnum = 0;/初始化仿真器void init() /* initialize the simulator */int i;float sum, avg;float jimsra
37、nd();FILE *fp;fp = fopen ("parameter.txt","r");printf("- Stop and Wait Network Simulator Version 1.1 - nn");printf(" -停止等待网络模拟器版本1.1 - nn");printf("回车输入包的个数给虚拟器: ");/fscanf(fp,"%d",&nsimmax); scanf("%d",&nsimmax);printf(&q
38、uot;n输入包被丢失的可能性输入 0.0 表示不丢失: ");/fscanf(fp, "%f",&lossprob);scanf("%f",&lossprob);printf("n输入包被损坏的可能性输入 0.0 表示不损坏:");/fscanf(fp,"%f",&corruptprob);scanf("%f",&corruptprob); printf("n输入包从发送方第五层到达的平均时间 > 0.0: "); /fsca
39、nf(fp,"%f",&lambda);scanf("%f",&lambda); printf("n输入跟踪: ");/fscanf(fp,"%d",&TRACE);scanf("%d",&TRACE);printf("nn");srand(9999); /* init random number generator */sum = 0.0; /* test random number generator for students */for
40、(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("It is likely that random number generation on your machinen" ); printf("is different from what this emulator expects. Please taken"); pri
41、ntf("a look at the routine jimsrand() in the emulator code. Sorry. n"); exit(0); */ printf("%f",avg);ntolayer3 = 0;nlost = 0;ncorrupt = 0;time=0.0; /* initialize time to 0.0 */ generate_next_arrival(); /* initialize event list */随机数发生器float jimsrand() double mmm = 2147483647; /*
42、largest int - MACHINE DEPENDENT! */float x; /* individual students may need to change mmm */ x = rand()/mmm; /* x should be uniform in 0,1 */return(x); /*/*事件处理部分*void generate_next_arrival()double x,log(),ceil();struct event *evptr;float ttime;int tempint;/if (TRACE>2)/printf("-GENERATE NEX
43、T ARRIVAL: creating new arrivaln");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 (jimsrand()<0.5)evptr->eventity = A;elseevptr->even
44、tity = B;insertevent(evptr);/向事件列表中插入一条新的事件void insertevent(struct event *p) struct event *q,*qold;if (TRACE>2)/printf(" INSERTEVENT: time is %lfn",time);/printf(" INSERTEVENT: future time will be %lfn",p->evtime); q = evlist; /* q points to front of list in which p struct
45、inserted q指针指向表前部当p结构被插入*/if (q=NULL)/* 表是空的*/ 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)/* 表尾 */ qold->next = p; p->prev = qold; p->next = NULL;else if (q=evlist)/* front of list */ p-
46、>next=evlist; p->prev=NULL; p->next->prev=p; evlist = p;else /* 表中部 */ p->next=q; p->prev=q->prev; q->prev->next=p; q->prev=p;/打印事件列表void printevlist()struct event *q;int i;printf("-n事件列表如下:n");for(q = evlist; q!=NULL; q=q->next)printf("事件时间: %f, 类型: %
47、d 实体: %dn",q->evtime,q->evtype,q->eventity); printf("-n");/启动计时器void starttimer(int AorB,float increment)struct event *q;struct event *evptr;if (TRACE>2)printf("n-A: 启动计时器: 在 %f 开始定时n",time);/* 友好的:检查计时器是否早已开始计时,如果是,则发出警告*/* for (q=evlist; q!=NULL && q-&g
48、t;next!=NULL; q = q->next) */for (q=evlist; q!=NULL ; q = q->next)if ( (q->evtype=TIMER_INTERRUPT && q->eventity=AorB) ) /printf("Warning: attempt to start a timer that is already startedn");return;/* 创建事件当超时发生 */evptr = (struct event *)malloc(sizeof(struct event);evptr->evtime = time + increment;evptr->evtype
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 扫黑除恶考试题目及答案
- 2026年导游资格证考试模拟试卷及答案(共八套)
- 2024-2025学年反射疗法师大赛理论考试综合练习及完整答案详解【夺冠系列】
- 2024-2025学年度注册公用设备工程师自我提分评估含答案详解(考试直接用)
- 2026年医保基金使用监管条例考试试题及答案
- 2024-2025学年度公务员考试《常识》考前冲刺练习(夺冠系列)附答案详解
- 2024-2025学年公务员考试《常识》考试彩蛋押题及参考答案详解
- 2024-2025学年山西警官职业学院单招数学考前冲刺练习试题含答案详解(考试直接用)
- 2024-2025学年度火电电力职业鉴定模考模拟试题【能力提升】附答案详解
- 2024-2025学年中级软考模拟试题附答案详解【黄金题型】
- 肉羊高效健康养殖与疫病防控技术培训
- 养老院食品安全培训
- -世界水日主题班会课件
- 全球核安全形势课件
- 《婴幼儿常见病识别与预防》高职早期教育专业全套教学课件
- 《智能制造基础与应用》课件全套 第1-8章 绪论、智能制造数字化基础- 智能制造应用
- 供电所所长安全演讲
- 急腹症临床诊断思维及程序
- 第三章-儿童游戏的分类与发展
- 音乐学校乐器购买合同
- HG∕T 5209-2017 黄磷生产尾气处理处置方法
评论
0/150
提交评论