1、ARQ协议的实现 ARQ协议的实现一实验目的 要求学生掌握Socket编程 及ARQ协议2实验内容1.必须采用应答机制、超时计数器技术、帧编号技术、重传技术2.校验和技术可选,a) 校验和s的计算:设要发送n字节,bi为第i个字,s=(b0+b1+bn) mod 2563.在接收端,设置随机数,根据随机数执行相关操作,0代表正常,1代表帧丢失,2代表帧出错,3代表应答帧丢失(即不发生应答帧)4.使用图形界面,b) 发送端:显示发送的数据、是否重传、本次帧序号、接收到的应答帧的序号c) 接收端:显示接收到的数据、本次帧序号、本次随机选择的出错情况、发送应答帧的序号、是否重复3实验流程1.发送端打
2、开窗口,准备发送数据,服务器端启动设备,打开端口,监听各个端口,采用的是多路复用技术,大大缓解了网络阻塞问题2.服务器端设置随机出错状态3.客户端点击发送数据(如果发送的数据没有收到应答的帧超过5个,即发送窗口已满,不再发送)4.正常情况下服务器端会收到数据并发送应答帧,帧或应答帧丢失时或帧出错时丢弃,客户端会启动超时重传,5.数据发送完毕后关闭 4关键技术1.流套接字:流套接字(SOCK_STREAM):流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP(The
3、Transmission Control Protocol)协议。2.多路复用技术Int PASCAL FAR WSAAsyncSelect (SOCKET s,HWND hWnd,unsigned int wMsg,long lEvent);本函数用来请求Windows Sockets DLL为窗口句柄发一条消息无论它何时检测到由lEvent参数指明的网络事件.要发送的消息由wMsg参数标明.被通知的套接口由s标识.3.ARQ协议 选择重传(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层的错误纠正协议之一。它包括停止等待ARQ协议和连续ARQ协议,错误侦测
4、(Error Detection)、正面确认(Positive Acknowledgment)、逾时重传(Retransmission after Timeout)与负面确认继以重传(Negative Acknowledgment and Retransmission)等机制。4.MFC技术 MFC(Microsoft Foundation Classes),是一个微软公司提供的类库(class libraries),以C+类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和
5、组件的封装类五源代码 1.client: WORD CCClientDlg:CRC(unsigned char *p,int len) WORD crc=0; unsigned char i; while(len-) for(i=0x80;i!=0;i=i1) if(crc&0x8000)!=0) crc=crc1; crc=crc0x1021; else crc=crc=5) MessageBox(发送窗口大于5!); else ret =send(m_hSocket,(char *)bufNumSend,bufNumSend0,0); ListNum+; if(ret!=bufNumSen
6、d0) TRACE(Send Error:%dn,WSAGetLastError(); return; postimerNum=0; m_TimertimerNum=SetTimer(timerNum+1,1000,NULL); timerNum=(timerNum+1)%8; NumSend=(NumSend+1)%8; char str10; itoa(NumSend,str,10); m_Stc_Send=str; UpdateData(FALSE); else MessageBox(请准备好发送帧!); void CCClientDlg:StartUp() WSADATA wsadat
7、a; WORD version=MAKEWORD(2,0); int ret=WSAStartup(version,&wsadata); if(ret!=0) TRACE(Initialize Error!n); void CCClientDlg:OnConfig() / TODO: Add your control notification handler code here UpdateData(TRUE); int i=0; CString data8; data0=m_Data1; data1=m_Data2; data2=m_Data3; data3=m_Data4; data4=m
8、_Data5; data5=m_Data6; data6=m_Data7; data7=m_Data8; for(i=0;i8;i+) if(datai=) MessageBox(请讲帧填写完整!); return; for(i=0;i8;i+) int strNum; unsigned char *fell; fell=(unsigned char *)datai.GetBuffer(0); crc=CRC(fell,datai.GetLength(); strNum=datai.GetLength(); bufi=new unsigned charstrNum+4; bufi0=(char
9、)(datai.GetLength()+4); for(int j=1;jm_hWnd,WM_MY_MESSAGE,FD_READ); this-InitProg();void CCClientDlg:CleanUp() if(WSACleanup()!=0) TRACE(UnInitialize Error:%dn,WSAGetLastError(); void CCClientDlg:OnCancel() / TODO: Add your control notification handler code here if(m_hSocket!=NULL) closesocket(m_hSo
10、cket); m_hSocket=NULL; CDialog:OnCancel();void CCClientDlg:OnDestroy() CDialog:OnDestroy(); / TODO: Add your message handler code here CleanUp();void CCClientDlg:BackStc(int m,int type) if(!type) switch(m) case 0: m_Stc1=重传; break; case 1: m_Stc2=重传; break; case 2: m_Stc3=重传; break; case 3: m_Stc4=重
11、传; break; case 4: m_Stc5=重传; break; case 5: m_Stc6=重传; break; case 6: m_Stc7=重传; break; case 7: m_Stc8=重传; break; else switch(m) case 0: m_Stc1=不重传; break; case 1: m_Stc2=不重传; break; case 2: m_Stc3=不重传; break; case 3: m_Stc4=不重传; break; case 4: m_Stc5=不重传; break; case 5: m_Stc6=不重传; break; case 6: m
12、_Stc7=不重传; break; case 7: m_Stc8=不重传; break; void CCClientDlg:setProg(int m) switch(m) case 0: m_Prog1.SetPos(posm); break; case 1: m_Prog2.SetPos(posm); break; case 2: m_Prog3.SetPos(posm); break; case 3: m_Prog4.SetPos(posm); break; case 4: m_Prog5.SetPos(posm); break; case 5: m_Prog6.SetPos(posm)
13、; break; case 6: m_Prog7.SetPos(posm); break; case 7: m_Prog8.SetPos(posm); break; void CCClientDlg:OnTimer(UINT nIDEvent) / TODO: Add your message handler code here and/or call default CDialog:OnTimer(nIDEvent); int num; num=nIDEvent-1; if(posnum=30) ret =send(m_hSocket,(char *)bufnum,bufnum0,0); B
14、ackStc(num,0); UpdateData(FALSE); posnum=0; if(ret!=bufnum0) TRACE(Send Error:%dn,WSAGetLastError(); return; else posnum+; setProg(num); void CCClientDlg: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_P
15、rog4.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);LRESULT CCClientDlg:OnMyMessage(WPARAM wParam, LPARAM lParam) int cm; if(WSAGETSELEC
16、TERROR(lParam) closesocket(wParam); return 0; if(WSAGETSELECTEVENT(lParam)=FD_READ) char num; ret=recv(m_hSocket,&num,1,0); if(ret=0|ret=SOCKET_ERROR) TRACE(Recv data error:%dn,WSAGetLastError(); return 0; cm=num-1; KillTimer(m_Timercm); ListNum-; BackStc(cm,1); char str10; itoa(cm+1,str,10); m_Stc_
17、RECV=str; UpdateData(FALSE); return 0;int CCClientDlg:OnCreate(LPCREATESTRUCT lpCreateStruct) if (CDialog:OnCreate(lpCreateStruct) = -1) return -1; / TODO: Add your specialized creation code here return 0;2.server: void CCServerDlg:OnOk() / TODO: Add your control notification handler code here CStri
18、ng Error4=正常,出错,帧丢失,应答帧丢失; srand(unsigned)time(NULL); m_StcE0=ErrorENum0=rand()%4; m_StcE1=ErrorENum1=rand()%4; m_StcE2=ErrorENum2=rand()%4; m_StcE3=ErrorENum3=rand()%4; m_StcE4=ErrorENum4=rand()%4; m_StcE5=ErrorENum5=rand()%4; m_StcE6=ErrorENum6=rand()%4; m_StcE7=ErrorENum7=rand()%4; UpdateData(FAL
19、SE);void CCServerDlg:OnSetserver() / TODO: Add your control notification handler code here 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_AN
20、Y; m_addr.sin_port=htons(1314); ret=bind(m_hSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr); if(ret=SOCKET_ERROR) TRACE(Bind Eoor:%dn,(error=WSAGetLastError(); return; AfxMessageBox(服务器开始启动); WSAAsyncSelect(m_hSocket,AfxGetMainWnd()-m_hWnd,WM_MY_MESSAGE,FD_ACCEPT); ret=listen(m_hSocket,5); if(ret=SOCKET_E
21、RROR) TRACE(Listen Error:%dn,(error=WSAGetLastError(); return; void CCServerDlg:StartUp() WSADATA wsaData; WORD version=MAKEWORD(2,0); int ret=WSAStartup(version,&wsaData); if(ret!=0) TRACE(Initialize Error!n);void CCServerDlg:CleanUp() if(WSACleanup()!=0) TRACE(UnInitialize error:%dn,WSAGetLastErro
22、r(); void CCServerDlg:SetEdit(char * str,int m) switch(m) case 0: if(ENum0=0|ENum0=3) if(m_Data0=str) m_StcR0=重复; m_Data0=str; break; case 1: if(ENum1=0|ENum1=3) if(m_Data1=str) m_StcR1=重复; m_Data1=str; break; case 2: if(ENum2=0|ENum2=3) if(m_Data2=str) m_StcR2=重复; m_Data2=str; break; case 3: if(ENu
23、m3=0|ENum3=3) if(m_Data3=str) m_StcR3=重复; m_Data3=str; break; case 4: if(ENum4=0|ENum4=3) if(m_Data4=str) m_StcR4=重复; m_Data4=str; break; case 5: if(ENum5=0|ENum5=3) if(m_Data5=str) m_StcR5=重复; m_Data5=str; break; case 6: if(ENum6=0|ENum6=3) if(m_Data6=str) m_StcR6=重复; m_Data6=str; break; case 7: if(ENum7=0|ENum7=3) if(m_Data7=str) m_StcR7=重复; m_Data7=str; break; UpdateData(FALSE);
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2