计算机网络实验二

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

哈尔滨工业大学计算机网络实验报告(2016年度春季学期)姓名:蔡鹏学号:1130310726学院:计算机科学与技术学院教师:李晓烽计算机网络实验报告-1-实验二一、实验目的理解滑动窗口协议的基本原理;掌握GBN的工作原理;掌握基于UDP设计并实现一个GBN协议的过程与技术。二、实验环境1.接入internet的实验主机2.Windows7操作系统3.Visualstadio2015c++语言三、实验内容1)基于UDP设计一个简单的GBN协议,实现单向可靠数据传输(服务器到客户的数据传输)。2)模拟引入数据包的丢失,验证所设计协议的有效性。四、实验过程及结果服务器端:使用UDP协议传输数据(比如传输一个文件),等待客户端的请求,接收并处理来自客户端的消息(如数据传输请求),当客户端开始请求数据时进入“伪连接”状态(并不是真正的连接,只是一种类似连接的数据发送的状态),将数据打包成数据报发送,然后等待客户端的ACK信息,同时启动计时器。当收到ACK时,窗口滑动,正常发送下一个数据报,计时器重新计时;若在计时器超时前没有收到ACK,则全部重传窗口内的所以已发送的数据报。具体实现:1)命令解析为了测试客户端与服务器端的通信交互,方便操作,设置了此过程。首先,服务器接收客户端发来的请求数据,“-time”表示客户端请求获取当前时间,服务器回复当前时间;“-quit”表示客户端退出,服务器回复“Goodbye!”;“-testgbn”表示客户端请求开始测试GBN协议,服务器开始进入GBN传输状态;其他数据,则服务器直接回复原数据。2)数据传输数据帧格式定义在以太网中,数据帧的MTU为1500字节,所以UDP数据报的数据部分应小于1472字节(除去IP头部20字节与UDP头的8字节),为此,定义UDP数据报的数据部分格式为:data计算机网络实验报告-2-Seq0Seq为1个字节,取值为0~255,(故序列号最多为256个);Data≤1024个字节,为传输的数据;最后一个字节放入EOF0,表示结尾。客户端:使用UDP协议向服务器端请求数据,接收服务器端发送的数据报并返回确认信息ACK(注意GBN为累积确认,即若ACK=1和3,表示数据帧2已经正确接收),必须能够模拟ACK丢失直至服务器端超时重传的情况。1)ACK数据帧定义由于是从服务器端到客户端的单向数据传输,因此ACK数据帧不包含任何数据,只需要将ACK发送给服务器端即可。ACK字段为一个字节,表示序列号数值;末尾放入0,表示数据结束。2)命令设置客户端的命令和服务器端的解析命令向对应,获取当前用户输入并发送给服务器并等待服务器返回数据,如输入“-time”得到服务器的当前时间。“-testgbn[X][Y]”命令,[X],[y]均为[0,1]的小数,其中:[X]表示客户端的丢包率,模拟网络中报文丢失;[Y]表示客户端的ACK的丢失率。(使用随机函数完成)。如果用户不输入,则默认丢失率均为0.2。源代码及注释:Client.cpp://GBN_client.cpp:定义控制台应用程序的入口点。//#includeiostream#includestdlib.h#includeWinSock2.h#includetime.h#pragmacomment(lib,ws2_32.lib)#defineSERVER_PORT12340//接收数据的端口号#defineSERVER_IP127.0.0.1//服务器的IP地址constintBUFFER_LENGTH=1026;constintSEQ_SIZE=20;//接收端序列号个数,为1~20Ack0计算机网络实验报告-3-/****************************************************************//*-time从服务器端获取当前时间-quit退出客户端-testgbn[X]测试GBN协议实现可靠数据传输[X][0,1]模拟数据包丢失的概率[Y][0,1]模拟ACK丢失的概率*//****************************************************************/voidprintTips(){printf(*****************************************\n);printf(|-timetogetcurrenttime|\n);printf(|-quittoexitclient|\n);printf(|-testgbn[X][Y]totestthegbn|\n);printf(*****************************************\n);}//************************************//Method:lossInLossRatio//FullName:lossInLossRatio//Access:public//Returns:BOOL//Qualifier:根据丢失率随机生成一个数字,判断是否丢失,丢失则返回TRUE,否则返回FALSE//Parameter:floatlossRatio[0,1]//************************************BOOLlossInLossRatio(floatlossRatio){intlossBound=(int)(lossRatio*100);intr=rand()%101;if(r=lossBound){returnTRUE;}returnFALSE;}intmain(intargc,char*argv[]){//加载套接字库(必须)WORDwVersionRequested;WSADATAwsaData;//套接字加载时错误提示interr;//版本2.2wVersionRequested=MAKEWORD(2,2);//加载dll文件Scoket库err=WSAStartup(wVersionRequested,&wsaData);计算机网络实验报告-4-if(err!=0){//找不到winsock.dllprintf(WSAStartupfailedwitherror:%d\n,err);return1;}if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2){printf(CouldnotfindausableversionofWinsock.dll\n);WSACleanup();}else{printf(TheWinsock2.2dllwasfoundokay\n);}SOCKETsocketClient=socket(AF_INET,SOCK_DGRAM,0);SOCKADDR_INaddrServer;addrServer.sin_addr.S_un.S_addr=inet_addr(SERVER_IP);addrServer.sin_family=AF_INET;addrServer.sin_port=htons(SERVER_PORT);//接收缓冲区charbuffer[BUFFER_LENGTH];ZeroMemory(buffer,sizeof(buffer));intlen=sizeof(SOCKADDR);//为了测试与服务器的连接,可以使用-time命令从服务器端获得当前时间//使用-testgbn[X][Y]测试GBN其中[X]表示数据包丢失概率//[Y]表示ACK丢包概率printTips();intret;intinterval=1;//收到数据包之后返回ack的间隔,默认为1表示每个都返回ack,0或者负数均表示所有的都不返回ackcharcmd[128];floatpacketLossRatio=0.2;//默认包丢失率0.2floatackLossRatio=0.2;//默认ACK丢失率0.2//用时间作为随机种子,放在循环的最外面srand((unsigned)time(NULL));while(true){gets_s(buffer);ret=sscanf(buffer,%s%f%f,&cmd,&packetLossRatio,&ackLossRatio);//开始GBN测试,使用GBN协议实现UDP可靠文件传输if(!strcmp(cmd,-testgbn)){printf(%s\n,BegintotestGBNprotocol,pleasedon'taborttheprocess);printf(Thelossratioofpacketis%.2f,thelossratioofackis%.2f\n,packetLossRatio,ackLossRatio);intwaitCount=0;intstage=0;计算机网络实验报告-5-BOOLb;unsignedcharu_code;//状态码unsignedshortseq;//包的序列号unsignedshortrecvSeq;//接收窗口大小为1,已确认的序列号unsignedshortwaitSeq;//等待的序列号sendto(socketClient,-testgbn,strlen(-testgbn)+1,0,(SOCKADDR*)&addrServer,sizeof(SOCKADDR));while(true){//等待server回复设置UDP为阻塞模式recvfrom(socketClient,buffer,BUFFER_LENGTH,0,(SOCKADDR*)&addrServer,&len);switch(stage){case0://等待握手阶段u_code=(unsignedchar)buffer[0];if((unsignedchar)buffer[0]==205){printf(Readyforfiletransmission\n);buffer[0]=200;buffer[1]='\0';sendto(socketClient,buffer,2,0,(SOCKADDR*)&addrServer,sizeof(SOCKADDR));stage=1;recvSeq=0;waitSeq=1;}break;case1://等待接收数据阶段seq=(unsignedshort)buffer[0];//随机法模拟包是否丢失b=lossInLossRatio(packetLossRatio);if(b){printf(Thepacketwithaseqof%dloss\n,seq);continue;}printf(recvapacketwithaseqof%d\n,seq);//如果是期待的包,正确接收,正常确认即可if(!(waitSeq-seq)){++waitSeq;if(waitSeq==21){waitSeq=1;}//输出数据printf(%s\n,&buffer[1]);计算机网络实验报告-6-buffer[0]=seq;recvSeq=seq;buffer[1]='\0';}else{//如果当前一个包都没有收到,则等待Seq为1的数据包,不是则不返回ACK(因为并没有上一个正确的ACK)if(!recvSeq){continue;}buffer[0]=recvSeq;buffer[1]='\0';}b=lossInLossRatio(ackLossRatio);if(b){printf(Theackof%dloss\n,(unsignedchar)buffer[0]);continue;}sendto(socketClient,buffer,2,0,(SOCKADDR*)&addrServer,sizeof(SOCKADDR));printf(sendaackof%d\n,(uns

1 / 16
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功