ARQ协议的实现.docx

上传人:b****0 文档编号:17279167 上传时间:2023-07-23 格式:DOCX 页数:25 大小:31.65KB
下载 相关 举报
ARQ协议的实现.docx_第1页
第1页 / 共25页
ARQ协议的实现.docx_第2页
第2页 / 共25页
ARQ协议的实现.docx_第3页
第3页 / 共25页
ARQ协议的实现.docx_第4页
第4页 / 共25页
ARQ协议的实现.docx_第5页
第5页 / 共25页
ARQ协议的实现.docx_第6页
第6页 / 共25页
ARQ协议的实现.docx_第7页
第7页 / 共25页
ARQ协议的实现.docx_第8页
第8页 / 共25页
ARQ协议的实现.docx_第9页
第9页 / 共25页
ARQ协议的实现.docx_第10页
第10页 / 共25页
ARQ协议的实现.docx_第11页
第11页 / 共25页
ARQ协议的实现.docx_第12页
第12页 / 共25页
ARQ协议的实现.docx_第13页
第13页 / 共25页
ARQ协议的实现.docx_第14页
第14页 / 共25页
ARQ协议的实现.docx_第15页
第15页 / 共25页
ARQ协议的实现.docx_第16页
第16页 / 共25页
ARQ协议的实现.docx_第17页
第17页 / 共25页
ARQ协议的实现.docx_第18页
第18页 / 共25页
ARQ协议的实现.docx_第19页
第19页 / 共25页
ARQ协议的实现.docx_第20页
第20页 / 共25页
亲,该文档总共25页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

ARQ协议的实现.docx

《ARQ协议的实现.docx》由会员分享,可在线阅读,更多相关《ARQ协议的实现.docx(25页珍藏版)》请在冰点文库上搜索。

ARQ协议的实现.docx

ARQ协议的实现

ARQ协议的实现

一.实验目的

要求学生掌握Socket编程及ARQ协议

2.实验内容

1.必须采用应答机制、超时计数器技术、帧编号技术、重传技术

2.校验和技术可选,

a)校验和s的计算:

设要发送n字节,bi为第i个字,s=(b0+b1+…+bn)mod256

3.在接收端,设置随机数,根据随机数执行相关操作,0代表正常,1代表帧丢失,2代表帧出错,3代表应答帧丢失(即不发生应答帧)

4.使用图形界面,

b)发送端:

显示发送的数据、是否重传、本次帧序号、接收到的应答帧的序号

c)接收端:

显示接收到的数据、本次帧序号、本次随机选择的出错情况、发送应答帧的序号、是否重复

3.实验流程

1.发送端打开窗口,准备发送数据,服务器端启动设备,打开端口,监听各个端口,采用的是多路复用技术,大大缓解了网络阻塞问题

2.服务器端设置随机出错状态

3.客户端点击发送数据(如果发送的数据没有收到应答的帧超过5个,即发送窗口已满,不再发送)

4.正常情况下服务器端会收到数据并发送应答帧,帧或应答帧丢失时或帧出错时丢弃,客户端会启动超时重传,

5.数据发送完毕后关闭

4.关键技术

1.流套接字:

流套接字(SOCK_STREAM):

流套接字用于提供面向连接、可靠的数据传输服务。

该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。

流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP(TheTransmissionControlProtocol)协议。

2.多路复用技术

IntPASCALFARWSAAsyncSelect(SOCKETs,HWNDhWnd,

unsignedintwMsg,longlEvent);

本函数用来请求WindowsSocketsDLL为窗口句柄发一条消息-无论它何时检测到由lEvent参数指明的网络事件.要发送的消息由wMsg参数标明.被通知的套接口由s标识.

3.ARQ协议

选择重传(AutomaticRepeat-reQuest,ARQ)是OSI模型中数据链路层的错误纠正协议之一。

它包括停止等待ARQ协议和连续ARQ协议,错误侦测(ErrorDetection)、正面确认(PositiveAcknowledgment)、逾时重传(RetransmissionafterTimeout)与负面确认继以重传(NegativeAcknowledgmentandRetransmission)等机制。

4.MFC技术

MFC(MicrosoftFoundationClasses),是一个微软公司提供的类库(classlibraries),以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。

其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类

五.源代码

1.client:

WORDCCClientDlg:

:

CRC(unsignedchar*p,intlen)

{

WORDcrc=0;

unsignedchari;

while(len--)

{

for(i=0x80;i!

=0;i=i>>1)

{

if((crc&0x8000)!

=0)

{

crc=crc<<1;

crc=crc^0x1021;

}

else

{

crc=crc<<1;

}

if((*p&i)!

=0)

{

crc=crc^0x1021;

}

}

p++;

}

returncrc;

}

voidCCClientDlg:

:

OnOk()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

if(judgeFirst)

{

if(ListNum>=5)

{

MessageBox("发送窗口大于5!

");

}

else

{

ret=send(m_hSocket,(char*)buf[NumSend],buf[NumSend][0],0);

ListNum++;

if(ret!

=buf[NumSend][0])

{

TRACE("SendError:

%d\n",WSAGetLastError());

return;

}

pos[timerNum]=0;

m_Timer[timerNum]=SetTimer(timerNum+1,1000,NULL);

timerNum=(timerNum+1)%8;

NumSend=(NumSend+1)%8;

charstr[10];

itoa(NumSend,str,10);

m_Stc_Send=str;

UpdateData(FALSE);

}

}

else

{

MessageBox("请准备好发送帧!

");

}

}

voidCCClientDlg:

:

StartUp()

{

WSADATAwsadata;

WORDversion=MAKEWORD(2,0);

intret=WSAStartup(version,&wsadata);

if(ret!

=0)

{

TRACE("InitializeError!

\n");

}

}

voidCCClientDlg:

:

OnConfig()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

UpdateData(TRUE);

inti=0;

CStringdata[8];

data[0]=m_Data1;

data[1]=m_Data2;

data[2]=m_Data3;

data[3]=m_Data4;

data[4]=m_Data5;

data[5]=m_Data6;

data[6]=m_Data7;

data[7]=m_Data8;

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

{

if(data[i]=="")

{

MessageBox("请讲帧填写完整!

");

return;

}

}

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

{

intstrNum;

unsignedchar*fell;

fell=(unsignedchar*)data[i].GetBuffer(0);

crc=CRC(fell,data[i].GetLength());

strNum=data[i].GetLength();

buf[i]=newunsignedchar[strNum+4];

buf[i][0]=(char)(data[i].GetLength()+4);

for(intj=1;j<=strNum;j++)

buf[i][j]=data[i][j-1];

buf[i][j]=HIBYTE(crc);

buf[i][j+1]=LOBYTE(crc);

buf[i][j+2]=(char)i;

//MessageBox(str);

}

m_Start=0;

m_End=i-1;

UpdateData(FALSE);

if(m_hSocket!

=NULL)

{

closesocket(m_hSocket);

m_hSocket=NULL;

}

if(m_hSocket==NULL)

{

m_hSocket=socket(AF_INET,SOCK_STREAM,0);

ASSERT(m_hSocket!

=NULL);

}

CStringSeverIp;

SeverIp="127.0.0.1";

m_addr.sin_family=AF_INET;

m_addr.sin_port=htons(1314);

m_addr.sin_addr.S_un.S_addr=inet_addr(SeverIp.GetBuffer(0));

ret=connect(m_hSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr));

if(ret==SOCKET_ERROR)

{

TRACE("ConnectError:

%d\n",(error=WSAGetLastError()));

if(error==10061)

AfxMessageBox(_T("连接失败!

"));

return;

}

judgeFirst=1;

m_Stc_Send="0";

UpdateData(FALSE);

WSAAsyncSelect(m_hSocket,AfxGetMainWnd()->m_hWnd,WM_MY_MESSAGE,FD_READ);

this->InitProg();

}

voidCCClientDlg:

:

CleanUp()

{

if(WSACleanup()!

=0)

{

TRACE("UnInitializeError:

%d\n",WSAGetLastError());

}

}

voidCCClientDlg:

:

OnCancel()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

if(m_hSocket!

=NULL)

{

closesocket(m_hSocket);

m_hSocket=NULL;

}

CDialog:

:

OnCancel();

}

voidCCClientDlg:

:

OnDestroy()

{

CDialog:

:

OnDestroy();

//TODO:

Addyourmessagehandlercodehere

CleanUp();

}

voidCCClientDlg:

:

BackStc(intm,inttype)

{

if(!

type)

switch(m)

{

case0:

m_Stc1="重传";

break;

case1:

m_Stc2="重传";

break;

case2:

m_Stc3="重传";

break;

case3:

m_Stc4="重传";

break;

case4:

m_Stc5="重传";

break;

case5:

m_Stc6="重传";

break;

case6:

m_Stc7="重传";

break;

case7:

m_Stc8="重传";

break;

}

else

switch(m)

{

case0:

m_Stc1="不重传";

break;

case1:

m_Stc2="不重传";

break;

case2:

m_Stc3="不重传";

break;

case3:

m_Stc4="不重传";

break;

case4:

m_Stc5="不重传";

break;

case5:

m_Stc6="不重传";

break;

case6:

m_Stc7="不重传";

break;

case7:

m_Stc8="不重传";

break;

}

}

voidCCClientDlg:

:

setProg(intm)

{

switch(m)

{

case0:

m_Prog1.SetPos(pos[m]);

break;

case1:

m_Prog2.SetPos(pos[m]);

break;

case2:

m_Prog3.SetPos(pos[m]);

break;

case3:

m_Prog4.SetPos(pos[m]);

break;

case4:

m_Prog5.SetPos(pos[m]);

break;

case5:

m_Prog6.SetPos(pos[m]);

break;

case6:

m_Prog7.SetPos(pos[m]);

break;

case7:

m_Prog8.SetPos(pos[m]);

break;

}

}

voidCCClientDlg:

:

OnTimer(UINTnIDEvent)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

CDialog:

:

OnTimer(nIDEvent);

intnum;

num=nIDEvent-1;

if(pos[num]>=30)

{

ret=send(m_hSocket,(char*)buf[num],buf[num][0],0);

BackStc(num,0);

UpdateData(FALSE);

pos[num]=0;

if(ret!

=buf[num][0])

{

TRACE("SendError:

%d\n",WSAGetLastError());

return;

}

}

else

{

pos[num]++;

setProg(num);

}

}

voidCCClientDlg:

:

InitProg()

{

m_Prog1.SetRange(0,30);

m_Prog1.SetStep

(1);

m_Prog2.SetRange(0,30);

m_Prog2.SetStep

(1);

m_Prog3.SetRange(0,30);

m_Prog3.SetStep

(1);

m_Prog4.SetRange(0,30);

m_Prog4.SetStep

(1);

m_Prog5.SetRange(0,30);

m_Prog5.SetStep

(1);

m_Prog6.SetRange(0,30);

m_Prog6.SetStep

(1);

m_Prog7.SetRange(0,30);

m_Prog7.SetStep

(1);

m_Prog8.SetRange(0,30);

m_Prog8.SetStep

(1);

}

LRESULTCCClientDlg:

:

OnMyMessage(WPARAMwParam,LPARAMlParam)

{

intcm;

if(WSAGETSELECTERROR(lParam))

{

closesocket(wParam);

return0;

}

if(WSAGETSELECTEVENT(lParam)==FD_READ)

{

charnum;

ret=recv(m_hSocket,&num,1,0);

if(ret==0||ret==SOCKET_ERROR)

{

TRACE("Recvdataerror:

%d\n",WSAGetLastError());

return0;

}

cm=num-1;

KillTimer(m_Timer[cm]);

ListNum--;

BackStc(cm,1);

charstr[10];

itoa(cm+1,str,10);

m_Stc_RECV=str;

UpdateData(FALSE);

}

return0;

}

intCCClientDlg:

:

OnCreate(LPCREATESTRUCTlpCreateStruct)

{

if(CDialog:

:

OnCreate(lpCreateStruct)==-1)

return-1;

//TODO:

Addyourspecializedcreationcodehere

return0;

}

2.server:

voidCCServerDlg:

:

OnOk()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

CStringError[4]={"正常","出错","帧丢失","应答帧丢失"};

srand((unsigned)time(NULL));

m_StcE0=Error[ENum[0]=rand()%4];

m_StcE1=Error[ENum[1]=rand()%4];

m_StcE2=Error[ENum[2]=rand()%4];

m_StcE3=Error[ENum[3]=rand()%4];

m_StcE4=Error[ENum[4]=rand()%4];

m_StcE5=Error[ENum[5]=rand()%4];

m_StcE6=Error[ENum[6]=rand()%4];

m_StcE7=Error[ENum[7]=rand()%4];

UpdateData(FALSE);

}

voidCCServerDlg:

:

OnSetserver()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

if(m_hSocket!

=NULL)

{

closesocket(m_hSocket);

m_hSocket=NULL;

}

if(m_hSocket==NULL)

{

m_hSocket=socket(AF_INET,SOCK_STREAM,0);

ASSERT(m_hSocket!

=NULL);

}

m_addr.sin_family=AF_INET;

m_addr.sin_addr.S_un.S_addr=INADDR_ANY;

m_addr.sin_port=htons(1314);

ret=bind(m_hSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr));

if(ret==SOCKET_ERROR)

{

TRACE("BindEoor:

%d\n",(error=WSAGetLastError()));

return;

}

AfxMessageBox("服务器开始启动");

WSAAsyncSelect(m_hSocket,AfxGetMainWnd()->m_hWnd,WM_MY_MESSAGE,FD_ACCEPT);

ret=listen(m_hSocket,5);

if(ret==SOCKET_ERROR)

{

TRACE("ListenError:

%d\n",(error=WSAGetLastError()));

return;

}

}

voidCCServerDlg:

:

StartUp()

{

WSADATAwsaData;

WORDversion=MAKEWORD(2,0);

intret=WSAStartup(version,&wsaData);

if(ret!

=0)

TRACE("InitializeError!

\n");

}

voidCCServerDlg:

:

CleanUp()

{

if(WSACleanup()!

=0)

{

TRACE("UnInitializeerror:

%d\n",WSAGetLastError());

}

}

voidCCServerDlg:

:

SetEdit(char*str,intm)

{

switch(m)

{

case0:

if(ENum[0]==0||ENum[0]==3)

{

if(m_Data0==str)

m_StcR0="重复";

m_Data0=str;

}

break;

case1:

if(ENum[1]==0||ENum[1]==3)

{

if(m_Data1==str)

m_StcR1="重复";

m_Data1=str;

}

break;

case2:

if(ENum[2]==0||ENum[2]==3)

{

if(m_Data2==str)

m_StcR2="重复";

m_Data2=str;

}

break;

case3:

if(ENum[3]==0||ENum[3]==3)

{

if(m_Data3==str)

m_StcR3="重复";

m_Data3=str;

}

break;

case4:

if(ENum[4]==0||ENum[4]==3)

{

if(m_Data4==str)

m_StcR4="重复";

m_Data4=str;

}

break;

case5:

if(ENum[5]==0||ENum[5]==3)

{

if(m_Data5==str)

m_StcR5="重复";

m_Data5=str;

}

break;

case6:

if(ENum[6]==0||ENum[6]==3)

{

if(m_Data6==str)

m_StcR6="重复";

m_Data6=str;

}

break;

case7:

if(ENum[7]==0||ENum[7]==3)

{

if(m_Data7==str)

m_StcR7="重复";

m_Data7=str;

}

break;

}

UpdateData(FALSE);

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

当前位置:首页 > PPT模板 > 其它模板

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2