




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、计算机通信网络实验数据链路层协议的设计与 实现学院: 班级: 学号: 姓名: 2012年11月11日实验目的计算机网络的数据链路层协议保证通信双方在有差错的通信线路上进行无差错的数据 传输,是计算机网络各层协议中通信控制功能最典型的一种协议。本实验实现一个数据链路层协议的数据传送部分,目的在丁更好地理解基本数据链路层协议的基本工作原理,掌握计算机网络协议的基本实现技术。实验内容使用C语言实现下面数据链路层协议:1. 分析和实现一个理想的链路层协议2. 对丁前面实现的协议进行扩充,实现它的第一次改进,如何防止发方过快淹没收方。3. 对上一步再假设在不可靠的的链路上进行通信。12345实验步骤熟悉
2、数据链路层协议的功能;编写数据链路层协议的实现程序;调试并运行自己编写的协议实现程序;了解协议的工作轨迹,如出现异常情况,在实验报告中写出原因分析保留你实现的数据链路层协议,以备教师检查。四、实验过程1、程序功能及设计思路功能概述:用客户端/服务器模式代表A站、B站。先由客户端输入服务器IP地址,发送SYN同步 帧,告诉服 务器准备接受。客户端输入数据后,会进行CR码,再发送数据帧;服务器收到后,先进行校验,数据正确则发送ACK帧,客户端则发送下一帧数据;否则服务器发送 NAKM,客户端重新发送该数据。CRCK 验:1) 将收到的字符转为int型(32位),并将其二进制码左移 16位,存丁 d
3、ata ;2) 进行 C( D)=Remainder ( S (D) 1DAL) /g (D), 即卩 CR ( K 验,得到校验 位。3) 将校验位加在信息元后,组成24位的码字,存丁要发送的数据帧dframe。停等式ARQft、议:Client: 1 ) 置 SN=02) 收到数据,将 SN 分配给该数据,如果没有收到,则等待;3) 存丁要发送的数据帧中,发送给 server ;如果从 server 收到确认帧, 且 RN>SN 贝 U SN 加 1 ( 模 2),返回 2;如果收到 NA 触 RN=SN 则返回 3,重传数据。1、发 RN 送 AC的地址值的长度版本Server :
4、1) 置 RN=02) 从 client 收到一个 SN=RN 勺帧,进行 CRg 验检查,无错后输出,并置 加 制;否则发送 NAO, 请求重发。2、 C 语言程序代码: 客户端 Client:心心心心心心心 *client.c#include<winsock.h> /WINSOCK API 的头文件,需要包含在项目中 #pragma comment(lib,"ws2_32.lib") /WINSOCK API 连接库文件 #include<stdio.h>#include<string.h>int err;SOCKET sock; /
5、 用丁服务器监听的 SocketSOCKADDR_IN addrSrv; / 服务端地址unsigned char sendBuf100; / 发送缓存char serverIp20; / 客户端 ip 地址 int socklen=sizeof(SOCKADDR_IN); /Socket int cf_len=sizeof(struct sockaddr);struct dataFrame / 数据帧( int seq; /分段消息的序号int SN; /发送序号unsigned int data100;int msglen; / 字符长度, 采用长度计数的组帧技术;struct conFr
6、ame / 控制帧( int RN; / 接收序号 char type3;表明帧的类型 :SYN 同步、 EOTS 毕、 ACK A 认应答、 NCKS 定应答;struct dataFrame dframe; struct conFrame*cframe;/*void initialization() ( WORD wVersionRequested;WSADATA wsaData; wVersionRequested = MAKEWORD( 1, 1 ); /WinSocket1.1return;/*计算卄Crc16*err = WSAStartup( wVersio “Requested
7、, &wsaData ); /wsaData用来存储系统传回的关丁WinSocket的资料if ( LOBYTE( wsaData.wVersion ) != 1 | H IB YTE( wsaData.wVersion ) != 1 )(WSAClea nu p();int i,j;/ char s32; /用丁测试时显示二进制码基丁 32位系统,int型长度为4字节,CRC-16的生成多项式为 g(D)=DA16+DA15+DA2+1 void caculate_crc16( un sig ned char*msg,i nt len th, un sig ned int *crc)
8、(un sig ned int data=0;for(i=0;i<le nth;i+,crc+,msg+)( data=(i nt)*msg;/ itoa(data,s,2); /把整数转为二进制码/ printf("第£ | 字的二进制码: %sn",i+1,s); /test *crc=data<<16;for(j=0;j<16;j+)(if(data&0x8000)(data=(data<<1)&0 xffff; data=dataA0x8005;else data=(data<<1)&
9、0 xffff;*crc=*crc|data; /把校验位放在信息元后面,存在一个int变量中/itoa(*crc,s,2);/ printf("力口上 CR 锻验位后的二进制码:%sn",s); /test /* void SendFrame()( /建立socket,SOCK_DGRAM 使用不连续不可靠的数据包连接sock=socket(AFN ET,SOCK_DGRAM,0); if(sock=-1)(printf("Building a socket failed.'n");return;发送数据帧*printf("input
10、 server's IP:"); scanf("%s",serverlp); /输入服务器 ipaddrSrv .sin _addr.S_ un. S_addr= in et_addr(serverlp); /址设置服务器地addrSrv .sin_family=AFNET;addrSrv.sin_port=htons(6000); / 设置服务器端 口 号 strcpy(cframe.type,"SYN");cframe.RN=0; / 发送同步消息 sendto(sock,(char*)&cframe,sizeof(cfra
11、me)+1,0,(SOCKADDR*)&addrSrv,sock len);printf(" n");dframe.seq=0;while(1) memset(sendBuf,0,sizeof(sendBuf); / 活空缓冲区 printf("Input the message:"); / 输入 message 若输入 exit 贝 U 停止发送 scanf("%s",sendBuf);if(strcmp(sendBuf,"exit")=0) / 当客户端要断开连接时,给服务器发送 EOTX 毕控制帧 s
12、trcpy(cframe.type,"EOT");/ 发送 EON 肖息 sendto(sock,(char*)&cframe,sizeof(cframe)+1,0,(SOCKADDR *)&addrSrv,socklen);printf(" close socket! n");break; dframe.seq+; dframe.SN=dframe.seq%2; dframe.msglen=strlen(sendBuf); caculate crc16(sendBuf,dframe.msglen,dframe.data);/ sendt
13、o(sock,(char*)&dframe,sizeof(struct dataFrame),0,(SOCKADDR *)&addrSrv,socklen);while(1) recvfrom(sock,(char*)&cframe,sizeof(struct conFrame),0,(SOCKADDR *)&addrSrv,&cf_len); / 接受来自服务器的应答帧if(strcmp(cframe.type, "ACK")=0) / 如果收到 ACK 应答指令,则发 送下一个 message if(cframe.RN!=dfra
14、me.SN)deliveredprin tf(" message issuccessfully. n");break; else if(strcmp(cframe.type, "NAK")=O)|(cframe.RN=dframe.SN) prin tf(" message redeliverri ng. n");sen dto(sock,(char*)&dframe,sizeof(struct dataFrame),0,(SOCKADDR *)&addrSrv,sockle n); / 重发该消息closesocke
15、t(sock); / 关 闭连接return;void mai n()initialization(); / 初始化阶段,若返回值 err=0 , 则表示初始化成功 if(err) printf("Initialization falied.'n");exit(0);Sen dFrame();WSAClea nup();*end of program服务器 Server :/* server c *的头文件,需要包含在项目中连接库文件/WINSOCK API#in cludevw in sock.h>#pragma comme nt(lib,"ws2
16、_32 ib") /WINSOCK API #in clude<stdio.h>#in cludevstri ng.h> int err;SOCKET sock; / 用丁服务器监听的 Socket SOCKADDR_IN addrSrv; / 服务端地址 SOCKADDR_IN addrClie nt; / 客户端地址实际存储在 recvBuf 的地址的长度 的地址值的长度un sig ned char recvBuf100; /接受缓存int cf_len=sizeof(struct sockaddr); / int sockle n=sizeof(SOCKAD
17、DR_IN); /Socketstruct dataFrame / 数据帧 int seq; II分段消息的序号int SN; II 发送序号 unsigned int data100;int msglen; II字符长度,采用长度计数的组帧技术struct conF rame II int RN; IIchar type3;表明帧的类型:控制帧接收序号SYN同步、EOTS毕、AC颌认应答、NC雄定应答;struct dataFrame dframe;struct con Frame cframe;初始化*I I *void in itializati on()WORD wVersio “Re
18、quested;WSADATA wsaData;int err;wVersio “Requested = MAKEWORD( 1, 1 );wsm1*版本err =WSAStartup( wVersio nRequested, &wsaData );IIwsaData用来存储系统传回的关丁WinSgcget.的资料if ( LOB YTE( wsaData .wVersio n ) != 1 | H iByJwsaDawVersio n ) !=1 )WSAClea nup(); return;/ / *绑定端*void bin dport()addrSrv .sin_addr.S_u
19、 n. S_addr=hto nl(INADDR_A NY);设置服务器地址,INADDR_ANY示使用自己的IP地址设定端口为6000addrSrv .sin_family=AFNET; addrSrv .sin_port=hto ns(6000); /err=bi nd(sock,(LPSOCKADDR)&addrSrv,sizeof(SOCKADDR); return;void checkout(unsigned int *pdata,int lenth) int i,j;unsigned int temp;unsigned int data;unsigned char *msg
20、=recvBuf; /*msg 指向 recvBuf 的首地址 / unsigned char s32; / 用丁测试时显示二进制码for(i=0;i<lenth;i+,msg+)data=*pdata;temp=(data&0xff0000)>>16; / *msg=temp;/ itoa(data,s,2); / printf(" 收到的二进制码:将校验位活零,使信息位移到低 sn",s); /test8位使得到for(j=0;j<16;j+) / 有 16 位校验元,故循环操作 16 次, RemainderR(x)/g(x)if(da
21、ta&0x800000) data=(data<<1)&0xffffff; data=data A0x800500;else data=(data<<1)&0xffffff; if(data=0) strcpy(cframe.type,"ACK");/若 RemainderR(x)/g(x)=0 , 表示接收序歹 U 无误 else / 若 RemainderR(x)/g(x) ! =0,表示接收序歹 U 有误 return;strcpy(cframe.type,"NAK"); pdata+;return
22、; 发送及接受消息*void RecvFrame()printf(" serverwaitting. n");while(1) recvfrom(sock,(char*)&cframe,sizeof(struct conFrame),0,(SOCKADDR *)&addrClient,&cf_len); / 接受来自客户端的同步帧if(strcmp(cframe.type,"SYN")=0) printf(" connectwith %s. n",inet_ntoa(addrClient.sin_addr);b
23、reak;while(1)活空接收缓冲cf_len=sizeof(struct sockaddr); memset(recvBuf,0,sizeof(recvBuf); / 区 err=recvfrom(sock,(char*)&dframe,sizeof(structdataFrame),0,(SOCKADDR *)&addrClient,&cf_len); /接受来自客户端的数据帧if(err=9)/ 当客户端关闭 socket 时,发送过来的数据会使 err=9 ,则服务器也关闭 socket printf(" client close the sock
24、et! n");break; checkout(dframe.data,dframe.msglen);/ 调用 checkout() 函数, CRC 佥验接收消息是否正确 if(strcmp(cframe.type,"ACK")=0) printf("client:%sn",recvBuf);printf(" message is correct! n");cframe.RN=(dframe.SN+1)%2;else if(strcmp(cframe.type,"NAK")=0)cframe.RN=dfr
25、ame.SN; printf(" message is wrong!n"); sendto(sock,(char*)&cframe,sizeof(cframe),0,(SOCKADDR *)&addrClient,socklen);/发送 ACK# 或 NAK 贞 printf(" The end! n");return;void main()initialization(); / 初始化阶段,若返回值 err=0 , 则表示初始化成功 if(err!=0) printf("Intialization failed.n"
26、;); return; sock=socket(AF_INET,SOCK_DGRAM,0);/建立 socket,SOCK_DGRAM 使用不连续不可靠的数据包连接if(sock=-1)(prin tf("Buildi ng a socket failed .'n"); return;bindport(); / 绑定端口if(err!=O)(prin tf("Bi nding a socket failed.' n"); return;RecvFrame(); /接受客户端发送数据closesocket(sock); /关 闭连接WSAC
27、lea nu p();/*end of program3、实验结果测试1:在没有传输错误情况下,在dos界面显示的传递内容的二进制码和CRCJ验码Client: 222.25.162.196 ,发送数据 “ yl 显示 “ messageis delivered successfully 后关 闭连接。I_-?唁两掐实瞪? ink layerXd ient-DLLDebug <IientPLL.exeServer: 222.25.162.196 ,收到数据“ yl,与上图对比,码字正确,则正确输出数据"C EUsera'dE RDeskto夙通信网笔layerser? r-DLLDetjugserveLDLLeire&quo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论