CBN協(xié)議實現(xiàn)(c語言)_第1頁
CBN協(xié)議實現(xiàn)(c語言)_第2頁
CBN協(xié)議實現(xiàn)(c語言)_第3頁
CBN協(xié)議實現(xiàn)(c語言)_第4頁
CBN協(xié)議實現(xiàn)(c語言)_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、;.中文注釋編程實現(xiàn)一個GBN傳輸協(xié)議的發(fā)送方和接收方兩程序,采用編程語言不限,要求能將發(fā)送接收流程以及處理方法表現(xiàn)出來.附源代碼及注釋源代碼:三:GBN-CS.c#include "GBN.h"#include <stdio.h>#include <string.h>#include <stdlib.h>extern int TRACE ; /* 用于跟蹤 */ extern int nsim ; /* 當(dāng)前第5層到第4層的信息數(shù) */ extern int nsimmax; /*"msg"生成數(shù)量,直到停止,生成的

2、最大信息數(shù) */extern float time; /時間extern int packet_correct; /包的正確到達(dá)數(shù)extern int packet_resent; /包的重傳數(shù)extern struct event *evlist; /事件int main() /主函數(shù)struct event *eventptr;/變量,結(jié)構(gòu)體聲明struct msg msg2give;struct pkt pkt2give;int i,j;char c; init();/初始化 A_init();/A端初始化 B_init();/B端初始化 while (1) /循環(huán),用于每個包的傳送 e

3、ventptr = evlist; /* 從模擬器得到下一個事件 */ if (eventptr=NULL)goto terminate; evlist = evlist->next;/* 從事件清單改變該事件 */ if (evlist!=NULL)evlist->prev=NULL;if (TRACE >= 2)/打印與事件相關(guān)的信息printf("n事件時間: %f,",eventptr->evtime);printf(" 類型: %d",eventptr->evtype);if (eventptr->evtyp

4、e=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-&g

5、t;evtime; /* 更新下一個事件的時間 */if (nsim=nsimmax)break; /* 當(dāng)輸入包個數(shù)等于生成的最大包個數(shù),模擬器停止 */ if (eventptr->evtype = FROM_LAYER5 ) /如果事件調(diào)用來自第五層generate_next_arrival(); /* 為將來的包的到達(dá)做準(zhǔn)備 */ /* 將相同的信息轉(zhuǎn)換為字母字符串 */ j = nsim % 26; for (i=0; i<20; i+)msg2give.datai = 97 + j; if (TRACE>2)printf(" 學(xué)生發(fā)送的主要數(shù)據(jù)是: &q

6、uot;);for (i=0; i<20; i+)printf("%c", msg2give.datai);/打印信息printf("n"); nsim+;if (eventptr->eventity = A)/A端向外發(fā)送數(shù)據(jù)A_output(msg2give); else/B端向外發(fā)送數(shù)據(jù)B_output(msg2give); else if (eventptr->evtype = FROM_LAYER3)/如果事件調(diào)用來自第三層pkt2give.seqnum = eventptr->pktptr->seqnum; pk

7、t2give.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); /* 適當(dāng)?shù)膶嶓w*/else /* B端交付包*/B_input(pkt2give);free(eventptr->

8、pktptr); /* 釋放包的緩存 */else if (eventptr->evtype = TIMER_INTERRUPT)/計時器中斷情況if (eventptr->eventity = A) A_timerinterrupt();elseB_timerinterrupt();else /校檢,防止發(fā)生不可預(yù)料事件printf("內(nèi)部警告: 不可預(yù)知的事件類型! n"); free(eventptr); terminate:/終止 printf(" 模擬器停止在: %f s n ,從第五層發(fā)送了 %d個包n",time,nsim);

9、printf(" 正確發(fā)送包的個數(shù): %d n", packet_correct); printf(" 重發(fā)包的個數(shù): %d n", packet_resent); system("pause");/暫停一GBN.h#pragma once#include <stdio.h>/基礎(chǔ)功能模塊的數(shù)據(jù)結(jié)構(gòu)聲明#define BIDIRECTIONAL 1 /* 改變值1如果你需要寫額外的可靠程序或B輸出程序(即B端系統(tǒng))*/* "msg"結(jié)構(gòu)體是由第五層(教師代碼)轉(zhuǎn)變成第四層的數(shù)據(jù)單元(學(xué)生代碼)*/*它包

10、括了經(jīng)由第五層向?qū)W生層協(xié)議通信實體交付的數(shù)據(jù)(字符)*/struct msg char data20;/* "pkt"結(jié)構(gòu)體是第4層(學(xué)生代碼)向第3層傳送的數(shù)據(jù)單元(老師代碼)。值得注意的是預(yù)先定義的包結(jié)構(gòu),這一切學(xué)生必須遵守。*/struct pktint seqnum;/順序號int acknum;/應(yīng)答號int checksum;/檢查和char payload20;#define WINDOWSIZE 8 /定義滑動窗口大小#define MAXBUFSIZE 50/最大窗口大小#define RTT 15.0/周游時間#define NOTUSED 0/沒用到#

11、define NACK -1/否定應(yīng)答#define TRUE 1#define FALSE 0#define A 0#define B 1/網(wǎng)絡(luò)仿真部分?jǐn)?shù)據(jù)結(jié)構(gòu)聲明*struct eventfloat evtime; /* 事件時間 */int evtype; /* 事件類型 */int eventity; /* 事件實體*/struct pkt *pktptr; /* 指向這個事件的指針(如果需要) */struct event *prev; /前一事件struct event *next; /后一事件 ;/* possible events: */#define TIMER_INTERR

12、UPT 0 /事件中斷#define FROM_LAYER5 1 /來自第五層#define FROM_LAYER3 2 /來自第三層#define OFF 0#define ON 1/基礎(chǔ)功能模塊的函數(shù)聲明*void ComputeChecksum(struct pkt *packet);/計算校驗和int CheckCorrupted(struct pkt packet);/檢查數(shù)據(jù)是否出錯void A_output( struct msg message);/A端向外發(fā)送數(shù)據(jù)void A_input(struct pkt packet);/A端接收數(shù)據(jù)void A_timerinterr

13、upt();/A計時器超時void A_init();/A端初始化void B_output(struct msg message); void B_input(struct pkt packet);void B_timerinterrupt();void B_init();/網(wǎng)絡(luò)仿真部分的函數(shù)聲明*void init(); /初始化仿真器float jimsrand();/隨機(jī)數(shù)發(fā)生器0,1/處理事件列表部分的函數(shù)聲明*void generate_next_arrival();/產(chǎn)生下一個到達(dá)的分組void insertevent(struct event *p);/向事件列表中插入一條新的

14、事件void printevlist();/打印事件列表/*/*計時器模塊*void stoptimer(int);/停止計時器void starttimer(int,float);/啟動計時器/*/*網(wǎng)絡(luò)各層之間傳送模塊*void tolayer3(int AorB,struct pkt packet);/向第3層發(fā)送信息void tolayer5(int AorB,char datasent20);/向第5層發(fā)送信息二:#include "GBN.h"#include <stdio.h>#include <string.h>#include &l

15、t;stdlib.h>extern int TRACE = 1; /* 用于跟蹤*/extern int nsim = 0; /* 當(dāng)前第5層到第4層的信息數(shù)*/ extern int nsimmax = 0; /* "msg"生成數(shù)量,直到停止*/extern float time = 0.000;float lossprob; /* 丟包可能性*/float corruptprob; /* 包的數(shù)據(jù)位數(shù)丟失可能性*/float lambda; /* 從第五層到達(dá)的比率 */ int ntolayer3; /* 送往第3層的包數(shù)量*/static int nlost

16、 = 0; /* 在媒體中丟失的包數(shù)量*/static int ncorrupt = 0; /* 在網(wǎng)絡(luò)中被破壞的包*/static int expectedseqnum = 0; /* 期待接收方發(fā)送的序號 */static int nextseqnum; /* 下一次發(fā)送方要使用的包序號*/static int base; /* 發(fā)送方頭窗*/struct pkt winbufWINDOWSIZE; /* 窗口包緩沖區(qū)*/static int winfront,winrear; /* 緩沖區(qū)的頭尾指針*/static int pktnum;/* 緩沖窗口包的數(shù)量*/struct msg b

17、ufferMAXBUFSIZE; /* 發(fā)送方數(shù)據(jù)緩沖區(qū)*/int buffront,bufrear; /* 緩沖區(qū)的頭尾指針 */static int msgnum;/* 緩沖窗口包的數(shù)量 */關(guān)于各種包的類型定義/*int packet_lost =0; /包丟失int packet_corrupt=0; /包破壞int packet_sent =0; /包發(fā)送extern int packet_correct=0;/正確包extern int packet_resent =0;/重發(fā)包int packet_timeout=0;/超時包extern struct event *evlist

18、 = NULL; /* 事件清單 */相關(guān)接口函數(shù)的實現(xiàn)/計算校驗和,即腳鏈和1的補(bǔ)碼和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->ch

19、ecksum = 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端向外發(fā)

20、送數(shù)據(jù)/* 被第五層調(diào)用,向另一端發(fā)送數(shù)據(jù)*/void A_output(struct msg message)int i;struct pkt sendpkt;/* 如果的發(fā)送方下次使用序號小于滑動窗口的最大序號,那么補(bǔ)發(fā)包*/if ( nextseqnum < base+WINDOWSIZE )printf("-A:新的包到達(dá),發(fā)送窗口不滿,新的包送往第3層!n");/* 創(chuàng)建包 */sendpkt.seqnum = nextseqnum;sendpkt.acknum = NOTUSED;for ( i=0; i<20 ; i+ ) sendpkt.payl

21、oadi = message.datai;/* 檢查是否出錯 */ComputeChecksum (&sendpkt); /* 送出包 */ tolayer3 (A, sendpkt); /* 復(fù)制這些包到窗口緩沖區(qū) */ winrear = (winrear+1)%WINDOWSIZE; pktnum +; winbufwinrear = sendpkt; for (i=0; i<20; i+) winbufwinrear.payloadi= sendpkt.payloadi; /* 更新狀態(tài)變量 */ nextseqnum = nextseqnum+1; starttimer

22、(A,RTT); B_input(sendpkt); A_input(sendpkt);/* 如果移動窗口包滿*/else printf("-A:新的包到達(dá),發(fā)送窗口已滿!");/* 如果緩沖區(qū)滿,放棄并退出*/if ( msgnum = MAXBUFSIZE)printf (" 錯誤:發(fā)送緩沖區(qū)已滿 !n"); exit (1); /* 否則,將信息送入緩沖區(qū) */ else printf("信息已送入緩沖區(qū)n"); bufrear = (bufrear+1) % MAXBUFSIZE; /擁塞控制,防止擁塞,減小緩沖區(qū) for (

23、i=0; i<20; i+) bufferbufrear.datai = message.datai; msgnum +; /B端向外發(fā)送數(shù)據(jù)/* 被第五層調(diào)用,發(fā)送數(shù)據(jù)到另一方,同A方相似 */void B_output(struct msg message)int i;struct pkt sendpkt;/* 如果發(fā)送窗口不滿*/if ( nextseqnum < base+WINDOWSIZE )printf("-B:新的包到達(dá),發(fā)送窗口不滿,新的包送往第3層!!n");/* create packet */sendpkt.seqnum = nextse

24、qnum;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 +; winb

25、ufwinrear = 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;/* 如果發(fā)

26、送窗口滿*/else printf("-B:新的包到達(dá),發(fā)送窗口已滿!,");/* if buffer full, give up and exit*/if ( msgnum = MAXBUFSIZE)printf (" 錯誤:發(fā)送緩沖區(qū)已滿 ! n"); exit (1); /* otherwise, buffer the message */ else printf("緩沖區(qū)滿!n"); bufrear = (bufrear+1) % MAXBUFSIZE; for (i=0; i<20; i+) bufferbufrear

27、.datai = message.datai; msgnum +; /A端接收數(shù)據(jù)void A_input(struct pkt packet)struct pkt sendpkt;int i;/* 如果收到?jīng)]有被破壞的包并且確認(rèn)包收到*/ if ( (CheckCorrupted(packet) = FALSE) && (packet.acknum != NACK) )printf("-A: ACK(確認(rèn)包) %d 被正確的收到,",packet.acknum);packet_correct+; /* 從窗口緩沖區(qū)刪去被確認(rèn)的包*/ winfront =

28、(winfront+(packet.acknum+1-base) % WINDOWSIZE; pktnum = pktnum - (packet.acknum+1-base); /* 改變窗口最小號確認(rèn)包 */ base = packet.acknum+1; stoptimer(A); if ( base < nextseqnum) /starttimer(A,RTT); printf ("nnn發(fā)送新的包!"); /* 如果緩沖區(qū)不空發(fā)送新的包*/ while ( (msgnum!=0) && (nextseqnum<base+WINDOWSI

29、ZE) )/* 創(chuàng)建包*/ sendpkt.seqnum = nextseqnum; sendpkt.acknum = NOTUSED; buffront = (buffront+1) % MAXBUFSIZE; for ( i=0; i<20 ; i+ ) sendpkt.payloadi = bufferbuffront.datai; /* 和確認(rèn)*/ ComputeChecksum (&sendpkt); /*如果是滑動窗口的第一個包,開始超時檢測*/ if ( base = nextseqnum ) /如果滑動窗口最小的包等于下一次要發(fā)送的序號/starttimer(A,

30、RTT);printf ("發(fā)送新的包!n"); /* 送出包 */ tolayer3 (A, sendpkt); /* 復(fù)制包到窗口緩沖區(qū) */ winrear = (winrear+1)%WINDOWSIZE; winbufwinrear = sendpkt; pktnum +; /* 更新狀態(tài)變量 */nextseqnum = nextseqnum+1; /* 刪除緩沖區(qū)的包 */msgnum -;else printf ("-A: 收到否定應(yīng)答,什么也沒有完成!n");/B端接收數(shù)據(jù)*一定要調(diào)用這個/* 這只是單一的A到B的傳送方式,沒有B端的數(shù)

31、據(jù)發(fā)出 */* 被第三層調(diào)用,但數(shù)據(jù)到達(dá)B端第4層*/void B_input(struct pkt packet) struct pkt sendpkt;int i;/*如果收到?jīng)]有被破壞的包并且確認(rèn)包收到 */if ( (CheckCorrupted(packet) = FALSE) && (packet.seqnum = expectedseqnum)printf("n-B: 包正確的到達(dá),發(fā)送ACK確認(rèn)包n",packet.seqnum);/* 發(fā)送應(yīng)答包 */ /* create packet */ sendpkt.seqnum = NOTUSED

32、; sendpkt.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 (期待下一次的發(fā)送序號)= %d

33、n",expectedseqnum); /* 發(fā)送包到第五層 */ /tolayer5(B,packet.payload); /* 否則,拋棄包,發(fā)送否定應(yīng)答*/ elseprintf("-B: 包 %d 損壞或者不是我所需要的, 發(fā)送否定應(yīng)答!n",packet.seqnum); /* 創(chuàng)建包 */ sendpkt.seqnum = NOTUSED; sendpkt.acknum = NACK; for ( i=0; i<20 ; i+ ) sendpkt.payloadi = '0' /* 校檢和檢查 */ ComputeChecksum

34、 (&sendpkt); /* 發(fā)出包 */ tolayer3 (B, sendpkt); /A計時器超時/* A超時被調(diào)用 */void A_timerinterrupt()int i;printf("-A:超時!重新發(fā)包!n");/* start timer */starttimer(A,RTT);/* 重新發(fā)送所有未被確認(rèn)的包*/for ( i=1; i<=pktnum; i+ )packet_resent+; tolayer3(A,winbuf(winfront+i)%WINDOWSIZE); /B計時器超時/* called when B's

35、 timer goes off */void B_timerinterrupt()int i;printf("-B: 超時!重新發(fā)包!n");/* start timer */starttimer(B,RTT);/* 重新發(fā)送所有未被確認(rèn)的包 */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

36、 */void 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

37、 jimsrand();FILE *fp;fp = fopen ("parameter.txt","r");printf("- Stop and Wait Network Simulator Version 1.1 - nn");printf(" -停止等待網(wǎng)絡(luò)模擬器版本1.1 - nn");printf("回車輸入包的個數(shù)給虛擬器: ");/fscanf(fp,"%d",&nsimmax); scanf("%d",&nsimmax); p

38、rintf("n輸入包被丟失的可能性輸入 0.0 表示不丟失: ");/fscanf(fp, "%f",&lossprob);scanf("%f",&lossprob);printf("n輸入包被損壞的可能性輸入 0.0 表示不損壞:");/fscanf(fp,"%f",&corruptprob);scanf("%f",&corruptprob); printf("n輸入包從發(fā)送方第五層到達(dá)的平均時間 > 0.0: "

39、); /fscanf(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 student

40、s */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("It is likely that random number generation on your machinen" ); printf("is different from what this emulator expects. Please taken&quo

41、t;); printf("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 */隨機(jī)數(shù)發(fā)生器float jimsrand() double mmm = 2147483

42、647; /* 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("-GENE

43、RATE NEXT 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-

44、>eventity = 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

45、 struct inserted q指針指向表前部當(dāng)p結(jié)構(gòu)被插入*/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 li

46、st */ p->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, 類型: %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(&

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論