停止等待协议实验报告文档格式.docx
- 文档编号:16597797
- 上传时间:2022-11-24
- 格式:DOCX
- 页数:20
- 大小:319.79KB
停止等待协议实验报告文档格式.docx
《停止等待协议实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《停止等待协议实验报告文档格式.docx(20页珍藏版)》请在冰豆网上搜索。
随着数据帧的到来,接收方对他们进行应答,可以每收到一帧给一个应答,也可以一次对若干帧进行应答。
如果一个帧到达时已经被破坏,接收方发送一个否定应答帧
(NAK)。
在数据链路层,差错控制主要指错误检测和重传方法。
在一个帧中出现任何一个错误,接收方就返回一个否定应答帧,出错的帧就被发送方重新传送。
这个过程被称作自动重复请
求(ARQ)。
数据被重传的情况有三种:
帧破坏、帧丢失和应答帧丢失。
流量控制和差错控制是结合在一起实现的,共有两种实现流量控制和差错控制的技术:
停止等待协议和滑动窗口协议。
其意义也注明在图3-24的右方。
值}(b)lc)4)
數撫趟從確賂上侵输的儿沖协况I
(□)况*2)数据•幅岀钳;
(C)数撫帧長矢:
(d)圳认凱去夫
可以用多种方法来表示一个有限状态机,对协议进行描述,以下只描述一种。
1)混合描述方法
1和状
比较实用的办法是合并一些状态,即考虑一些次要的细节。
例如,甲方的状态
态2,状态3和状态4都可以合并,乙的状态1和状态4,状态2和状态3也可进行合并。
这样可以用3个字符XYZ表示整个系统的状态,其中X=0或1,对应于甲方准备
发[0]或[1(包括发完后等待ACK的状态);
Y=0或1,对应于乙方期望收到[0]或[1];
Z=0、I、A或—,对应于信道上传送的是[0]、[1]、ACK或出现了差错(包括丢失)。
这样,
就可得出图3-24的有限状态机。
在弧线(或直线)旁边注明的数字为状态变迁的标号,
】收[□]・XACK,送圭机
2收ACK.^[1]
5吹[1]*发送主机
4收ACK,发[0]
5收回,SACK,不送主机
6收|1“SACK,不送主机
7超乩发[0]
8超时,发⑴
半取工诵信的停I卜等待协逗的有限状杰机
假设系统一开始处在(000)状态。
这表示甲发完[0],乙期望收到[0],而信道上传送的也是[0]。
在无差错的情况下,系统的状态仅在4个状态中循环:
(000)7(01A)7(111)T(10A)7(000)7……。
从理论上讲,应当共有2X2X4=16种不同的状态。
去掉没有意义的组合后,还剩下10种状态,而导致状态变迁的输人事件共有9种(标号
0~8)。
这种有限状态机可帮助我们检查协议是否正确。
例如,检查一下乙方会不会连续将两个
0号帧送交主机。
这相当于检查一下会不会出现这种情况,即在两次出现状态变迁1之间
不出现状态变迁3。
仔细检查图3-24就可发现这种情况是不会发生的。
同样方法也可用来排除连续将两个1号帧送交主机的可能。
再检查一下会不会发生甲方连续改变状态2次(如从0到1,再回到0)而乙方的
状态未改变。
这种情况相当于出现了未被发现的报文丢失。
可以看出,这种情况也是不存在
的。
协议必须不出现死锁。
死锁的出现是因为存在着这样的一种状态子集,其特点是:
从这
一子集变迁到子集外是不可能的,而在这一子集状态的变迁总是局限于子集的几个状态。
可
以看出,如图所示的自动机没有死锁现象。
3.设计方案论证
当收方收到一个正确的数据帧后,便会向发方发送一个确认帧ACK表示发送的数据正确
接收。
当发方收到确认帧后才能发送一个新的数据帧,这样就实现了接收方对发送方的流量
控制。
由于通信线路质量各方面的影响,数据帧从发送方到接收方传输的过程中可能会出现差错。
为了保证数据的正确性和完整性,接收方在收到数据后,会用一定的方法对接收到的
数据进行差错检验,所以接收方很容易检测出收到的数据帧是否出现差错。
当接收方发现收
到的数据出现差错时,就会向发送方发送一个否认帧NAK,表示对方发送的数据错误。
发送
方会根据接收方发来的信息做出相应的操作。
采用这样的有效的检错机制,数据链路层可以
对上面的网络层提供了可靠的传输的服务。
三、系统运行与验证
程序分两部分:
客户程序和服务器程序。
工作过程是:
服务器首先启动,它创建套接字
之后等待客户的连接;
客户启动后创建套接字,然后和服务器建立连接;
建立连接后,客户
写入文件的路径,然后将文件发送到服务器,服务器要求写入保存的文件路径,收到到文件
后,将接收到的文件保存到指定路径当中。
服务器端运行图:
客户端运行图
鬪C:
\V!
irdoW5\sy'
5tem32\cmd.e)ce
o回l»
-|
llj£
in£
fUinSock2.0CStatus:
Running〉
IwithAPIuersioris2.2to2.2
*
iFleaseinputreceiveriy:
成功发送文件后的
UsingfUinSock2.9Running〉
wit11APIversions2.2to2.2
Ple&
seinputFecaiuei*i)^:
127.0_Q_lIleaseinputth&
Fil?
path=G:
-txtfilcopensucceed
INQsendsucceed
send!
10UH
send吕uggu耳试
TOTsendconplete.sendsize;
^endsucceed
文件发送失败
客户端的响应
rawC:
\Window5^system32\cmd-fxe
丨二丨叵
UsingUinSock2.0<
St*tns-Runnifig)
withATI"
OF©
直orts2-2to2.2
E
F丄easeinputpeceiueu*
Pleaseinputthefilepath:
c:
\1.txtfileopensucceed
fil»
fAiltd
Fliesendfailed
客户端向服务器端发送文件请求ENQ但是没有收到返回帧,客户端显示sendfilefailed,
而filesendfailed表明文件经过规定次数重传后文件还是发送失败。
四、总结与体会
1.分组情况
润:
负责停止等待协议模拟客户端程序的编写、调试。
毛凤阳:
负责停止等待协议模拟服务端程序的编写、调试。
黄晓明:
负责查阅相关资料,实验报告的撰写,编写头文件。
2.总结
通过本次实验及课上老师讲解,对停止等待协议有了更深刻的了解。
并且通过C/S代码
的编写运行,形象地看到客户/服务器端的运作方式,对于C/S模型有了很深刻的印象以及
进一步理解。
通过代码的编写,再一次熟悉Socket编程原理,掌握简单的套接字编程。
运行程序成功后,是在同一台电脑上进行C与S端的连接。
而且使用的是TCP协议,所以要模拟停止等待协议发送丢包,超时等情况比较困难。
仅仅实现了文件发送时等待应答信
号超时的情况。
编程时遇到许多困难,从一个新手通过查阅相关的资料和以前的学习以及和同学之间的交流进步到逐步了解。
在设计过程中,组员之间相互促进,相互交流,共同进步。
发送端程序
IIsender.cpp:
定义控制台应用程序的入口点。
//
#include"
stdafx.h"
#inelude<
iostream>
WinSock2.h>
#include<
string.h>
#include"
../header/ARQ.h"
#include"
../header/Exception.h"
//服务器端口
#defineSERVER_PORT2280
//最大重传次数
#defineMAXRETRY8
//传送传时时间
设置link时的lib库,加入ws2_32.lib到工程,此
也可以在MFC过在project->
settings->
link中加
主要是获得Ws2_32.dll
#defineTIMEOUT3000
#pragmacomment(lib,"
ws2_32.lib"
)〃
库文件与socket编程有关
入
usingnamespacestd;
SOCKETPrimaryUDP;
//定义一个socket号charServerlP[20];
〃定义数组保存服务器的IP地址
charFilePath[MAX_PATH];
〃定义文件的路径存储数//用作奇偶检校的序号boolg_number=false;
//返回的控制字符
charg_bcc;
HANDLEm_hEvent;
voidInitWinSock()//初始化socket
{
WSADATAwsaData;
//TheWSADATAstructureisusedtostoreWindowsSocketsinitializationinformation
//returnedbyacalltotheAfxSocketInitglobalfunction.
if(WSAStartup(MAKEWORD(2,2),&
wsaData)!
=0)//TheWSAStartupfunction
initiatesuseofWs2_32.dllbyaprocess.
//TheMAKEWORDacrocreatesaWORDalueby
concatenatingthespecifiedvalues.
throwException("
Windowssockets2.2startupunsuccessful"
);
}
else{
printf("
Using%s(Status:
%s)\n"
.wsaData.szDescription,wsaData.szSystemStatus);
withAPIversions%d.%dto%d.%d\n\n"
LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion),LOBYTE(wsaData.wHighVersion),HIBYTE(wsaData.wHighVersion));
voidmksock(inttype)//创建socket号
PrimaryUDP=socket(AF_INET,type,0);
//socket()函数创建一个socket号
if(PrimaryUDP<
0)
createsocketerror"
voidBindSock()//绑定一个socket号和本地进程(用地址和端口号描述)
sockaddr_insin;
//定义一个套接字地址
sin.sin_addr.S_un.S_addr=INADDR_ANY;
//获取本地IP地址
sin.sin_family=AF_INET;
//协议族TCP/IP
sin.sin_port=0;
//系统随机获取端口号
if(bind(PrimaryUDP,(structsockaddr*)&
sin,sizeof(sin))<
0)//绑定
binderror"
}boolASendto()
sockaddr_inremote;
remote.sin_addr.S_un.S_addr=inet_addr(ServerIP);
remote.sin_family=AF_INET;
remote.sin_port=htons(SERVER_PORT);
intfromlen=sizeof(remote);
//打开文件
FILE*file;
说明文件只读并按二进制方式打
if((file=fopen(FilePath,"
rb"
))==NULL)//"
开
cout<
<
FilePath<
"
openerror"
endl;
returnfalse;
fileopensucceed"
//设置文件指针位置
SetFilePointer(file,0,NULL,FILE_BEGIN);
〃使FILE_BEGIN指向文件开头
BSCbsc;
bsc.header=STX;
bsc.tail=ETX;
//设置为有信号状态
SetEvent(m_hEvent);
//分段序号
boolnumber=false;
unsignedlongdwRead=-1;
boolsendComplete=false;
while(!
sendComplete)
//清空数据
memset(bsc.data,0,MAXBSCLENGTH);
把bsc.data前MAXBSCLENGTH符用代替
//当前分块的奇偶序号
bsc.number=number;
//记录当前的分块序号
g_number=bsc.number;
if(dwRead==-1)〃第一次应发送文件请求消息
//发送文件请求
bsc.bcc=ENQ;
//询问
ENQ"
;
char*filename=FilePath;
if((filename=strrchr(FilePath,'
\\'
))==NULL)〃在FilePath中寻找
字符,返回指向最后一个字符的指针
filename=FilePath;
//获取文件名
else
++filename;
strcpy(bsc.data,filename);
dwRead=0;
if(!
feof(file))〃如果没有检查到file的结束符
bsc.bcc=SYN;
//同步
SYN"
inti=fread(bsc.data,sizeof(char),MAXBSCLENGTH,file);
件读入bsc.data,返回字节数
read:
i<
\tsend:
sizeof(bsc.data)<
dwRead+=i;
//deRead等于读到的字节数
//发送完毕
bsc.bcc=EOT;
//结束
EOT"
sendComplete=true;
sendcomplete.sendsize:
dwRead<
fclose(file);
//MAXRETRY为最大达重传次数
for(inti=0;
MAXRETRY;
i++)
sendto(PrimaryUDP,(char*)&
bsc,sizeof(bsc),0,(sockaddr*)&
remote,fromlen);
ResetEvent(m_hEvent);
〃设置为无信号状态
DWORQslut=WaitForSingleObject(m_hEvent,TIMEOUT);
〃来,如果在TIMEOUT时间信号不到来,
待,函数返回,如果想让线程一直等待,需设置该参数为INFINITE
if(reslut==WAIT_OBJECT_0)〃说明事件是有信号状态返回
//收到应答消息,一种是ACK,一种是NAK
if(g_bcc==NAK)
if(i==MAXRETRY-1)
returnfalse;
//继续重传
continue;
//收到应答消息
sendsucceed"
break;
把文
等待信号的到
线程不再等
elseif(i==MAXRETRY-1)//没有收到返回帧
sendfilefailed"
//开始发下一段数据
number=!
number;
returntrue;
DWORDWINAPIARecv(LPVOIDIpParam)
intsinlen=sizeof(remote);
BSCbuffer;
intiread=0;
while(true)
iread
recvfrom(PrimaryUDP,(char*)&
buffer,sizeof(buffer),0,(sockaddr*)&
remote,&
sinlen)
5
//处理ACK与NAK
if(iread==SOCKET_ERROR)
//与当前的分块序号进行比较,看是不是当前块的应答
if(buffer.number!
=g_number)
if(buffer.bcc==ACK||buffer.bcc==NAK)
//保存返回的控制字符
g_bcc=buffer.bcc;
〃设置为有信号状态
}return0;
int_tmain(intargc,_TCHAR*argv[])〃main函数
InitWinSock();
mksock(SOCK_DGRAM);
BindSock();
Pleaseinputreceiverip:
cin>
>
ServerlP;
Pleaseinputthefilepath:
>
FilePath;
m_hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
//lfthefunctionsucceeds,thereturnvalueisahandle
//totheeventobject.
创建一个空事件对象,
返回一
个句柄
CreateThread(NULL,0,ARecv,NULL,0,NULL);
//TheCreateThreadfunction
createsathreadtoexecute
//within
thevirtual
address
spaceofthecallingprocess.
执行ARecv函数
if(!
ASendto())
filesendfailed"
getchar();
getchar();
return0;
接收端程序:
//receiver.cpp:
#include<
#pragmacomment(lib,"
)〃设置link时的lib库
charFileSavePath[MAX_PATH];
voidInitWinSock()
WSADATAwsaData;
=0)
wsaData.szDescripti
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 停止 等待 协议 实验 报告