计算机网络实验含全部5个的代码及文字指导.docx

上传人:b****3 文档编号:3824572 上传时间:2022-11-25 格式:DOCX 页数:32 大小:214.27KB
下载 相关 举报
计算机网络实验含全部5个的代码及文字指导.docx_第1页
第1页 / 共32页
计算机网络实验含全部5个的代码及文字指导.docx_第2页
第2页 / 共32页
计算机网络实验含全部5个的代码及文字指导.docx_第3页
第3页 / 共32页
计算机网络实验含全部5个的代码及文字指导.docx_第4页
第4页 / 共32页
计算机网络实验含全部5个的代码及文字指导.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

计算机网络实验含全部5个的代码及文字指导.docx

《计算机网络实验含全部5个的代码及文字指导.docx》由会员分享,可在线阅读,更多相关《计算机网络实验含全部5个的代码及文字指导.docx(32页珍藏版)》请在冰豆网上搜索。

计算机网络实验含全部5个的代码及文字指导.docx

计算机网络实验含全部5个的代码及文字指导

计算机网络原理

 

实验报告

学院:

信息院

专业班级:

计科0701

学号:

0902070110

姓名:

屈丽

指导老师:

桂劲松

 

实验一数据链路层后退N帧协议

1.1实验目的

模拟实现数据链路层后退n帧协议。

1.2实验内容

要求理解链路层后退n帧协议原理,编程动态实现数据链路层后退n帧协议。

1.3实验原理

1.3.1窗口机制

滑动窗口协议的基本原理,就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。

发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。

不同的滑动窗口协议窗口大小一般不同。

发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。

下面是一个例子(设发送窗口尺寸为2,接收窗口尺寸为1):

分析:

(1)初始态,发送方没有帧发出,发送窗口前后沿相重合。

接收方0号窗口打开,等待接收0号帧;

(2)发送方打开0号窗口,表示已发出0帧但尚未确认返回信息。

此时接收窗口状态不变;

(3)发送方打开0、1号窗口,表示0、1号帧均在等待确认。

至此,发送方打开的窗口数已达规定限度,在未收到新的确认返回帧之前,发送方将暂停发送新的数据帧。

接收窗口此时状态仍未变;

(4)接收方已收到0号帧,0号窗口关闭,1号窗口打开,表示准备接收1号帧。

此时发送窗口状态不变;

(5)发送方收到接收方发来的0号帧确认返回信息,关闭0号窗口,表示从重发表中删除0号帧。

此时接收窗口状态仍不变;

(6)发送方继续发送2号帧,2号窗口打开,表示2号帧也纳入待确认之列。

至此,发送方打开的窗口再次达到规定限度,在未收到新的确认返回帧之前,发送方将暂停发送新的数据帧,此时接收窗口状态仍不变;

(7)接收方已收到1号帧,1号窗口关闭,2号窗口打开,表示准备接收2号帧。

此时发送窗口状态不变;

(8)发送方收到接收方发来的1号帧收到的确认信息,关闭1号窗口,表示从重发表中删除1号帧。

此时接收窗口状态仍不变。

若从滑动窗口的观点来统一看待1比特滑动窗口、后退N及选择重传三种协议,它们的差别仅在于各自窗口尺寸的大小不同而已:

1比特滑动窗口协议:

发送窗口=1,接收窗口=1;

后退n协议:

发窗口>1,接收窗口>1;

选择重传协议:

发送窗口>1,接收窗口>1。

1.3.2比特滑动窗口协议

当发送窗口和接收窗口的大小固定为1时,滑动窗口协议退化为停-等协议(stop-and-wait)。

该协议规定发送方每发送一帧后就要停下来,等待接收方已正确接收的确认(acknowledgement)返回后才能继续发送下一帧。

由于接收方需要判断接收到的帧是新发送的帧还是重新发送的帧,因此发送方要为每一个帧加一个序号。

由于停等协议规定只有一帧完全发送成功后才能发送新的帧,因而只用1比特来编号就够了。

1.3.3后退N协议

任何时候,若带宽与往返延迟的乘积很大,则发送方就需要一个较大的窗口。

如果带宽很高的话,即使对于一个并不很长的延迟,发送方也会很快用完它的窗口,除非窗口真的非常大。

如果延迟很长,那么即使带宽并不高,发送方也会用完它的窗口。

这两个因子的乘积基本上说明了这条管道的容量,发送方为了达到尖峰效率,需要这条管道来马不停蹄的发送数据。

这项技术称为管道化技术。

使用管道化技术后,有两种方法可以用来处理错误。

一种方法是回退n帧(实验一),另一种则是选择性重传(实验二)。

由于停等协议要为每一个帧进行确认后才继续发送下一帧,大大降低了信道利用率,因此又提出了后退N协议。

后退N协议中,发送方在发完一个数据帧后,不停下来等待应答帧,而是连续发送若干个数据帧,即使在连续发送过程中收到了接收方发来的应答帧,也可以继续发送。

而且,发送方在每发送完一个数据帧时都要设置超时定时器。

只要在所设置的超时时间内仍收到确认帧,就要重发相应的数据帧。

例如:

当发送方发送了N个帧后,若发现这N帧的前一帧在计时器超时后仍未返回其确认信息,则该帧被判定为出错或丢失,此时发送方就不得不重新发送出错的这帧及其后的N帧。

从这里不难看出,后退N协议一方面因连续发送数据帧而提高了效率,但另一方面,在重传时又必须把原来已正确传送过的数据帧进行重传(仅因这些数据帧之前有一个数据帧出了错),这种做法又使传送效率降低。

由此可见,若传输信道的传输质量很差,因而误码率较大时,连续传送协议不一定优于停止-等待协议。

此协议中的发送窗口的大小为k,接收窗口仍是1。

1.4实验步骤

1.4.1编写程序

程序源代码如下:

#include"stdio.h"

#include"string.h"

#include"time.h"

#include"conio.h"

#include"graphics.h"

#defineN_BACKE2

#defineLENsizeof(structFrame)

intrandm(int,int);

intt;

intg_seq=1;

intg_pos=0;

structFrame

{

interr;/*出错标志*/

intout;/*发送标志*/

intseq;

intclock;

intack;

intcount;/*传输次数*/

structFrame*next;

}*sd,*re;

typedefstructFrameFra;

voidInsert(Fra**,Fra*);

voidinit()/*初始化就绪、阻塞、完成队列*/

{

sd=NULL;

re=NULL;

}

voiddelay(inta)/*时间延迟函数,用于实现数据帧的动态变化*/

{

clock_tstart=clock();/*系统时间函数*/

while(clock()-a*CLK_TCK<=start);

}

voidCreat()/*创建数据帧*/

{

Fra*p=(Fra*)malloc(LEN);

p->count=0;

p->out=0;/*已经发送标志*/

p->seq=g_seq;/*帧序号*/

p->clock=N_BACKE;/*最大后退次数*/

p->ack=0;/*接受确认*/

if(p->seq%t==0)

p->err=1;/*出错标志*/

else

p->err=0;

p->next=NULL;

Insert(&sd,p);

g_seq++;

}

voidInsert(Fra**v,Fra*p)/*将数据帧插入到V队列中*/

{

Fra*q;

q=*v;

if(*v==NULL)

{

q=p;

*v=q;

}

else

{

while(q->next!

=NULL)

q=q->next;

q->next=p;

}

}

voidsend(Fra*p)/*发送数据帧*/

{

charstr[10];

p->out=1;

if(p->err==0)/*发送未出错*/

{

p->ack=1;

setfillstyle(1,4);/*设置填充模式,用4号颜色—红表示正确发送*/

setcolor

(1);

circle(50+25*p->seq,150,10);/*画圆圈表示数据帧*/

floodfill(50+25*p->seq,150,1);

setcolor

(2);

itoa(p->seq,str,10);

outtextxy(45+25*p->seq,146,str);/*显示帧的编号*/

if(p->count>0)

{

setfillstyle(1,5);

setcolor

(1);

circle(50+25*p->seq,300,10);

floodfill(50+25*p->seq,300,1);

setcolor

(2);

itoa(p->seq,str,10);

outtextxy(45+25*p->seq,296,str);

}

}

else/*发送出错*/

{

setfillstyle(1,7);/*用7号颜色表示错误的发送*/

setcolor

(1);

circle(50+25*p->seq,150,10);

floodfill(50+25*p->seq,150,1);

setcolor(4);

itoa(p->seq,str,10);

outtextxy(45+25*p->seq,146,str);

if(p->count>0)

{

setfillstyle(1,5);

setcolor

(1);

circle(50+25*p->seq,300,10);

floodfill(50+25*p->seq,300,1);

setcolor

(2);

itoa(p->seq,str,10);

outtextxy(45+25*p->seq,296,str);

}

}

p->count++;

}

voidback_send(Fra**v)/*检查超时未确认的帧*/

{

charstr[10];

intpos;

Fra*p;

p=*v;

while(p!

=NULL)

{

if(p->ack==0&&p->clock==0)/*超时未发,取得该帧标号*/

{

g_pos=p->seq;

break;

}

elseif(p->out==1)

p->clock-=1;

p=p->next;

}

}

Fra*search(Fra**v,intnum)/*查找未确认帧对应的指针*/

{

Fra*p;

p=*v;

while(p!

=NULL)

{

if(p->seq==num)

returnp;

else

p=p->next;

}

}

intrandm(intx,inty)/*随机数函数*/

{

intk;

k=rand()%(x-y)+x;

returnk;

}

print(Fra**v)/*在屏幕上显示帧序列*/

{

intsize;

charstr[10];

void*buff;

Fra*p;

p=*v;

while(p!

=NULL)

{

setfillstyle(1,7);

setcolor

(1);

circle(50+25*p->seq,300,10);

floodfill(50+25*p->seq,300,1);

setcolor(4);

itoa(p->seq,str,10);

outtextxy(45+25*p->seq,296,str);

p=p->next;

}

size=imagesize(65,290,85,310);

buff=malloc(size);

getimage(65,290,85,310,buff);

p=*v;

while(!

kbhit())

{

putimage(40+25*p->seq,140,buff,COPY_PUT);

delay

(1);

send(p);

back_send(&sd);

if(g_pos!

=0)

{

p=(*search)(&sd,g_pos);

if(p->seq%t==0)

p->err=0;

}

else

p=p->next;

delay

(1);

g_pos=0;

}

}

voidmain()

{

inti,j;

intdriver=DETECT,mode;

initgraph(&driver,&mode,"");

cleardevice();

srand((unsigned)time(NULL));

t=randm(5,7);

for(i=0;i<20;i++)

{

Creat();

}

print(&sd);

getch();

}

1.4.2设计思路

本程序首先用Creat()函数创建了若干的数据帧,创建完毕后调用send(Fra*p)函数依次发送创建好的若干个数据帧,同时每发送一个帧就检查前面发送的帧是否有超时未被确认的,此功能由函数back_send(Fra**v)来完成。

若发现有超时未发则返回超时帧的序列号seq,同时根据seq调用超时帧查找函数*search(Fra**v,intnum)找到该帧位置,从该位置起全部从发后面的帧,即后退N帧协议。

1.5实验结果分析

1.5.1结果截图

1.5.2结果分析

根据后退N帧协议,当第5号帧发生错误时,第5、6、7帧全部重传(时间间隔为2个周期)。

实验二模拟实现数据链路层选择性重传协议

2.1实验目的

模拟实现数据链路层选择性重传协议。

2.2实验内容

要求编程动态实现数据链路层选择性重传协议,理解数据链路层选择性重传协议原理。

2.3实验原理

滑动窗口的基本原理同实验一。

2.3.1选择性重传协议原理

在后退N协议中,接收方若发现错误帧,就不再接收后续的帧,即便这些帧是正确到达的帧。

这显然是一种浪费。

另一种效率更高的策略是当接收方发现某帧出错后,其后继续送来的正确的帧虽然不能立即递交给接收方的高层,但接收方仍可收下来,存放在一个缓冲区中,同时要求发送方重新传送出错的那一帧。

一旦收到重新传来的帧后,就可以与已存于缓冲区中的其余帧一并按正确的顺序递交高层。

这种方法称为选择重发(SELECTIVEREPEAT),其工作过程如图所示。

显然,选择重发减少了浪费,但要求接收方有足够大的缓冲区空间。

2.4实验步骤

2.4.1编写程序

本实验的源程序和实验一基本一样,只是在某写数据的处理上有细微的差别。

即两个程序只在print(Fra**v)函数中找到超时未发数据帧的处理方面有点差别。

在实验一中,当找到超时数据帧时,直接丢弃后面的已发数据帧,即不保存后面帧的位置。

而选择性重传,由于它只重传超时的数据帧,并不重传所有的数据帧,所以当发现超时帧时,它必须先保存当前已发最后一个帧的位置,以便重发完超时帧后回到原来发送点。

voidprint(Fra**v)

{

intsize;

charstr[10];

void*buff;

Fra*p,*q;

p=*v;

while(p!

=NULL)

{

setfillstyle(1,7);

setcolor

(1);

circle(50+25*p->seq,300,10);

floodfill(50+25*p->seq,300,1);

setcolor(4);

itoa(p->seq,str,10);

outtextxy(45+25*p->seq,296,str);

p=p->next;

}

size=imagesize(65,290,85,310);

buff=malloc(size);

getimage(65,290,85,310,buff);

p=*v;

while(!

kbhit())

{

putimage(40+25*p->seq,140,buff,COPY_PUT);

delay

(1);

send(p);

q=p;

back_send(&sd);

if(g_pos!

=0)

{

p=(*search)(&sd,g_pos);

if(p->seq%t==0)

p->err=0;

send(p);

p=q;/*保存当前帧位置*/

p=p->next;

}

else

p=p->next;

delay

(1);

g_pos=0;

}

}

2.4.2设计思路

设计思路与实验一基本一样,不同点在上小节已详细介绍。

2.5实验结果分析

2.5.1结果截图

2.5.2结果分析

根据选择性重传协议,当6号帧发生错误时,只重传6号帧。

实验三:

距离向量路由算法的实现

3.1实验目的

模拟距离向量路由算法的路由表交换过程,演示每轮交换后路由表的变化。

3.2实验内容

要求编程实现距离矢量路由算法的路由表交换过程,并动态演示每轮交换过后路由表的变化情况。

3.3实验原理

距离向量路由算法,使用这个算法的路由器必须掌握这个距离表(它是一个一维排列,即一个向量),它告诉在网络中每个节点的最远和最近距离。

在距离表中的这个信息是根据临近接点信息的改变而时时更新的。

表中数据的量和在网络中的所有的接点(除了它自己本身)是等同的。

这个表中的列代表直接和它相连的邻居,行代表在网络中的所有目的地。

每个数据包括传送数据包到每个在网上的目的地的路径和距离/时间在那个路径上来传输(我们叫这个为“成本”)。

这个在那个算法中的度量公式是跳跃的次数,等待时间,流出数据包的数量等等。

在距离向量路由算法中,相邻路由器之间周期性地相互交换各自的路由表备份。

当网络拓扑结构发生变化时,路由器之间也将及时地相互通知有关变更信息。

每个路由器维护了一张路由表,它以子网中的每个路由器为索引,并且每个路由器对应一个表项。

该表项包含两部分:

为了达到该目标路由器而使用的输出线路,以及到达该目标路由器的时间估计值或者距离估计值。

距离矢量路由算法在理论中可以工作,但在实践中有一个严重的缺陷:

虽然它总是能够达到正确的答案,但是它收敛到正确答案的速度非常慢,尤其是,它对于好消息的反应非常快,但是对于坏消息的反应非常迟缓。

3.4实验步骤

3.4.1编写程序

程序的源代码如下:

#include"stdio.h"

#include"stdlib.h"

#include"alloc.h"

#defineROUTNUM7

typedefstruct

{

intdis;

intfrom;

}RoutNode;

RoutNodedata[ROUTNUM][ROUTNUM];/*路由表*/

voidInitData(FILE*pfile);/*从数据文件读取数据,初始化路由表*/

voidOutputRoutData();/*输出所有的路由表*/

voidCommunication(intrecv,intsend);/*send点向recv点发送自己的路由表*/

voidExchange();/*所有节点进行一次数据交换,更新路由表*/

voidmain()

{

intstart,end,i,j;

FILE*pfile;

pfile=fopen("1.txt","r");

if(pfile==NULL)

{

printf("文件打开错误,按任意键退出.\n");

getch();

return;

}

else

InitData(pfile);

fclose(pfile);

printf("\n路由表初始:

\n");

for(i=0;i

{

printf("%c||",i+65);

for(j=0;j

if(data[i][j].dis>0)

printf("<%c%d>",j+65,data[i][j].dis);

printf("\n");

}

for(i=0;i

{

Exchange();

}

printf("\n路由表交换:

\n");

OutputRoutData();

printf("输入起始路由节点(%d-%d):

",0,ROUTNUM-1);

scanf("%d",&start);

printf("输入终点路由节点(%d-%d):

",0,ROUTNUM-1);

scanf("%d",&end);

if(start==end||start<0||start>6||end<0||end>6)

{

printf("\n输入错误,请按任意键退出\n");

getch();

return;

}

else

{

intcur=start;

inttotal=0;

if(data[start][end].dis<0)

{

printf("没有路由路径发现!

\n");

getch();

return;

}/*endofif*/

printf("%c->",cur+65);

while(data[cur][end].from>=0)

{

total+=data[cur][data[cur][end].from].dis;

printf("%c->",data[cur][end].from+65);

cur=data[cur][end].from;

}/*endofwhile*/

total+=data[cur][end].dis;

printf("%c\n总的路由距离=%d",end+65,total);

getch();

return;

}/*endofelse*/

}

voidInitData(FILE*pfile)

{

charnum[10];

inti=0;

charc;

intm,n;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1