数据链路层协议的设计与实现.docx_第1页
数据链路层协议的设计与实现.docx_第2页
数据链路层协议的设计与实现.docx_第3页
数据链路层协议的设计与实现.docx_第4页
数据链路层协议的设计与实现.docx_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

计算机通信网络实验 数据链路层协议的设计与实现 学院: 班级: 学号: 姓名: 2012年11月11日一、 实验目的计算机网络的数据链路层协议保证通信双方在有差错的通信线路上进行无差错的数据传输,是计算机网络各层协议中通信控制功能最典型的一种协议。本实验实现一个数据链路层协议的数据传送部分,目的在于更好地理解基本数据链路层协议的基本工作原理,掌握计算机网络协议的基本实现技术。二、 实验内容使用C 语言实现下面数据链路层协议:1. 分析和实现一个理想的链路层协议2. 对于前面实现的协议进行扩充,实现它的第一次改进,如何防止发方过快淹没收方。3. 对上一步再假设在不可靠的的链路上进行通信。三、 实验步骤1. 熟悉数据链路层协议的功能;2. 编写数据链路层协议的实现程序;3. 调试并运行自己编写的协议实现程序;4. 了解协议的工作轨迹,如出现异常情况,在实验报告中写出原因分析;5. 保留你实现的数据链路层协议,以备教师检查。四、 实验过程1、程序功能及设计思路功能概述:用客户端/服务器模式代表A站、B站。先由客户端输入服务器IP地址,发送SYN同步帧,告诉服务器准备接受。客户端输入数据后,会进行CRC编码,再发送数据帧;服务器收到后,先进行校验,数据正确则发送ACK帧,客户端则发送下一帧数据;否则服务器发送NAK帧,客户端重新发送该数据。CRC校验:1) 将收到的字符转为int型(32位),并将其二进制码左移16位,存于data;2) 进行C(D)=Remainder(S(D)DL)/g(D) ,即CRC校验,得到校验位。3) 将校验位加在信息元后,组成24位的码字,存于要发送的数据帧dframe。停等式ARQ协议:Client: 1) 置SN=0;2) 收到数据,将SN分配给该数据,如果没有收到,则等待;3) 存于要发送的数据帧中,发送给server;4) 如果从server收到确认帧,且RNSN,则SN加1(模2),返回2;如果收到NAK或RN=SN,则返回3,重传数据。Server:1) 置RN=0;2) 从client收到一个SN=RN的帧,进行CRC校验检查,无错后输出,并置RN加1、发送ACK帧;否则发送NAK帧,请求重发。 2、C语言程序代码:客户端Client:/* client.c *#include /WINSOCK API的头文件,需要包含在项目中#pragma comment(lib,ws2_32.lib) /WINSOCK API连接库文件#include#includeint err;SOCKET sock; /用于服务器监听的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 conFrame /控制帧int RN; /接收序号char type3; /表明帧的类型:SYN同步、EOT送毕、ACK确认应答、NCK否定应答;struct dataFrame dframe;struct conFrame cframe;/* 初始化*void initialization() WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD( 1, 1 ); /WinSocket1.1版本 err = WSAStartup( wVersionRequested, &wsaData ); /wsaData用来存储系统传回的关于WinSocket的资料 if ( LOBYTE( wsaData.wVersion ) != 1 | HIBYTE( wsaData.wVersion ) != 1 )WSACleanup( ); return;/* 计算CRC-16*/基于32位系统,int型长度为4字节,CRC-16的生成多项式为g(D)=D16+D15+D2+1void caculate_crc16(unsigned char*msg,int lenth,unsigned int *crc)unsigned int data=0; int i,j;/ char s32; /用于测试时显示二进制码for(i=0;ilenth;i+,crc+,msg+)data=(int)*msg;/itoa(data,s,2); /把整数转为二进制码/printf(第%d字的二进制码:%sn,i+1,s); /test*crc=data16;for(j=0;j16;j+) if(data&0x8000)data=(data1)&0xffff;data=data0x8005;else data=(data1)&0xffff;*crc=*crc|data; /把校验位放在信息元后面,存在一个int变量中/itoa(*crc,s,2);/printf(加上CRC校验位后的二进制码:%sn,s); /test/*发送数据帧*void SendFrame()/建立socket,SOCK_DGRAM为使用不连续不可靠的数据包连接sock=socket(AF_INET,SOCK_DGRAM,0); if(sock=-1)printf(Building a socket failed.n);return;printf(input servers IP:); scanf(%s,serverIp); /输入服务器ip addrSrv.sin_addr.S_un.S_addr=inet_addr(serverIp); /设置服务器地址 addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000); / 设置服务器端口号 strcpy(cframe.type,SYN); cframe.RN=0;/发送同步消息sendto(sock,(char*)&cframe,sizeof(cframe)+1,0,(SOCKADDR*)&addrSrv,socklen); printf(-n);dframe.seq=0;while(1)memset(sendBuf,0,sizeof(sendBuf); /清空缓冲区printf(Input the message:); /输入message,若输入exit则停止发送scanf(%s,sendBuf);if(strcmp(sendBuf,exit)=0) /当客户端要断开连接时,给服务器发送EOT送毕控制帧 strcpy(cframe.type,EOT);/发送EOT消息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); /发送消息sendto(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!=dframe.SN)printf(-message is delivered successfully.-n);break;else if(strcmp(cframe.type, NAK)=0)|(cframe.RN=dframe.SN)printf(-message redeliverring.-n);sendto(sock,(char*)&dframe,sizeof(struct dataFrame),0,(SOCKADDR *)&addrSrv,socklen); /重发该消息closesocket(sock); /关闭连接 return;void main()initialization(); /初始化阶段,若返回值err=0,则表示初始化成功if(err)printf(Initialization falied.n);exit(0); SendFrame();WSACleanup();/* end of program *服务器Server:/* server.c *#include /WINSOCK API的头文件,需要包含在项目中#pragma comment(lib,ws2_32.lib) /WINSOCK API连接库文件#include#includeint err;SOCKET sock; /用于服务器监听的SocketSOCKADDR_IN addrSrv; /服务端地址SOCKADDR_IN addrClient; /客户端地址unsigned char recvBuf100; /接受缓存int cf_len=sizeof(struct sockaddr); /实际存储在recvBuf的地址的长度int socklen=sizeof(SOCKADDR_IN); /Socket的地址值的长度struct dataFrame /数据帧int seq; /分段消息的序号int SN; /发送序号unsigned int data100;int msglen; /字符长度,采用长度计数的组帧技术;struct conFrame /控制帧int RN; /接收序号char type3; /表明帧的类型:SYN同步、EOT送毕、ACK确认应答、NCK否定应答;struct dataFrame dframe;struct conFrame cframe; /* 初始化*void initialization() WORD wVersionRequested; WSADATA wsaData;int err; wVersionRequested = MAKEWORD( 1, 1 ); /WinSocket1.1版本 err = WSAStartup( wVersionRequested, &wsaData ); /wsaData用来存储系统传回的关于WinSocket的资料 if ( LOBYTE( wsaData.wVersion ) != 1 | HIBYTE( wsaData.wVersion ) != 1 )WSACleanup( ); return;/* 绑定端口 *void bindport() addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); /设置服务器地址,INADDR_ANY表示使用自己的IP地址 addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000); /设定端口为6000 err=bind(sock,(LPSOCKADDR)&addrSrv,sizeof(SOCKADDR);return;/* CRC校验 *void checkout(unsigned int *pdata,int lenth)int i,j;unsigned int temp;unsigned int data;unsigned char *msg=recvBuf; /*msg指向recvBuf的首地址/unsigned char s32; /用于测试时显示二进制码for(i=0;i16; /将校验位清零,使信息位移到低8位*msg=temp;/itoa(data,s,2); /把整数转为二进制码 /test/printf(收到的二进制码:%sn,s); /testfor(j=0;j16;j+) /有16位校验元,故循环操作16次,使得到RemainderR(x)/g(x) if(data&0x800000)data=(data1)&0xffffff;data=data0x800500;else data=(data1)&0xffffff;if(data=0)strcpy(cframe.type,ACK); /若RemainderR(x)/g(x)=0,表示接收序列无误else strcpy(cframe.type,NAK); /若RemainderR(x)/g(x)!=0,表示接收序列有误return;pdata+;return ;/* 发送及接受消息 *void RecvFrame()printf(-server waitting.-n);while(1)recvfrom(sock,(char*)&cframe,sizeof(struct conFrame),0,(SOCKADDR *)&addrClient,&cf_len); /接受来自客户端的同步帧if(strcmp(cframe.type,SYN)=0)printf(-connect with %s.-n,inet_ntoa(addrClient.sin_addr);break;while(1)cf_len=sizeof(struct sockaddr);memset(recvBuf,0,sizeof(recvBuf); /清空接收缓冲区err=recvfrom(sock,(char*)&dframe,sizeof(struct dataFrame),0,(SOCKADDR *)&addrClient,&cf_len); /接受来自客户端的数据帧if(err=9) /当客户端关闭socket时,发送过来的数据会使err=9,则服务器也关闭socketprintf(-client close the socket!-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=dframe.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);return;sock=socket(AF_INET,SOCK_DGRAM,0); /建立socket,SOCK_DGRAM为使用不连续不可靠的数据包连接if(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论