大连海事大学iptcp实验报告

专业班号____________________ 姓 名____________________ 实验日期____________________ 指导教师____________________ 第________实验 第_______组 实验名称 ______________________________ ARQ协议实现

一、 实验目的

1.实现一个简单的自动重发协议的模拟演示 2.了解LLC层网络协议的实现方法 3.掌握MFC中的系统计时器

4.初步掌握MFC的体系结构以及消息映射方法

5.掌握VC++中AppWizard和ClassWizard的基本使用方法。 6.了解LLC层部分协议的实现步骤。 7.了解模拟的简单的重发协议的流程。 8.理解对缓冲区与滑动窗口的概念。

二、 实验环境

1.开发语言 Visual C++ 6.0 2. 软件平台 Windows XP

三、 实验原理

1、 协议及网络状态的假设

(1) 发送方将一帧发出以及帧通过物理链路传送到接收方的总时间为tl; (2) 接收方对该帧进行处理的时间为tp; (3) 接收方发ACK或NAK帧的时间为ts;

(4) 发送方收到ACK或NAK帧,进行处理的时间为tr; (5) 重发计时器的过期时间为timeout;

(6) 物理链路存在一定的丢失率以及错误率; (7) 缓冲区窗口大小为1,采用1位编码 2、发送方发送

(1) vs设0;

(2) 从缓冲区读帧,如缓冲区为空,则发送结束; (3) 发送;

(4) 设超时计数器; (5) 等待;

(6) 收到ACK,vs转成下帧的序列号,清除缓冲区,缓冲区置下帧,转(2); (7) 收到NAK,转(3); (8) 计时器超时,转(3); 3、接收方接收

(1) vr设0;

(2) 等待;

(3) 收到数据帧,正确则继续,出错则转(8); (4) 帧号对时继续;否则丢弃当前帧,转(2) (5) 将帧送网络层;

(6) Vr转成下一帧序号; (7) 发送确认帧ACK,转(2); (8) 发送NAK,转(2)

四、 实验步骤

1. 新建工程,选择

MFC AppWizard[exe]

2。单击工作区面板上的Resources,放置各种需要的控件,右击控件,选择属性,可设置控件的ID和样式。

3.对前面命名的六个资源进行属性的设置,如下表所示,选中资源->单击右键->属性->样式

资源ID

IDC_EVE_SEND

类型 EDIT BOX

样式

Multiline选中

Vertical Scroll选中 Border选中 ReadOnly选中 Static Edge选中 Multiline选中

Vertical Scroll选中 Border选中 ReadOnly选中 Static Edge选中 Border选中

Static Edge选中 Number选中 Border选中

Want Return选中 Static Edge选中

资源对应变量 CString

m_eveSend

说明

发送方的事件将显示在这里

IDC_EVE_RECV EDIT BOX

CString

m_eveRecv 接收方的事件将显示在这里

IDC_BUFF IDC_TEXT STATIC TEXT

EDIT BOX

CString m_buff int m_size

缓冲区内容将显示在这里

得到用户需要发的帧个数

IDC_SEND IDC_SETTING

BUTTON BUTTON

CButton m_send CButton m_setting

发送n个帧进行演示

配置网络

4.用ClassWizard生成的方法添加成员变量,方法如下,选择“查看”->建立类向导->Member Variables

5.在资源面板中绘制新对话框IDD_SETTING,将对话框中样式的系统菜单选项不选中,如下图

双击对话框,ClassWizard将提示需要为该对话框资源制定一个类,选择Create a new class, 并取名为DlgSetting, 并按下图,表添加成员变量,并进行初始值设定

资源ID IDC_ERROR IDC_MISSING IDC_LATANCY IDC_TIMEOUT IDC_TP IDC_TS IDC_TR IDC_OK

类型 EDIT BOX EDIT BOX EDIT BOX EDIT BOX BUTTON EDIT BOX EDIT BOX Button

资源对应变量 int m_error int m_missing int m_tl

int m_timeout int m_tp int m_ts int m_tr

CButton m_ok

说明

帧出错率 帧丢失率 发送时延(ms)

重发计时计时器过时期限(ms)

接收方处理时间(ms) 处理ACK,NAK时间(ms) 发送ACK,NAK时间(ms) 设置完成

在DlgSetting.cpp的构造函数中加初始设定: DlgSetting::DlgSetting(CWnd* pParent /*=NULL*/) : CDialog(DlgSetting::IDD, pParent) { //{{AFX_DATA_INIT(DlgSetting)

// NOTE: the ClassWizard will add member initialization here m_error = 10; m_tl = 100; m_missing = 10; m_timeout =300; m_tp = 10; m_tr = 10; m_ts = 10; //}}AFX_DATA_INIT }

6.接下来进行具体的实现,首先是模拟网络的设置,在Setting对话框资源面板中双击OK按钮,添加单击事务,实现函数OnOk()

void DlgSetting::OnOK() { // TODO: Add extra validation here UpdateData(); if(m_error>100||m_error100||m_missing

7.整个设置对话框设置好了,接下来让它生效,在ARQDlg.h的开始处添加代码:

#if !defined(AFX_ARQDLG_H__7F277C47_32BA_4297_8A25_6D20F43064B9__INCLUDED_)

#define

AFX_ARQDLG_H__7F277C47_32BA_4297_8A25_6D20F43064B9__INCLUDED_

#include "DlgSetting.h" #if _MSC_VER > 1000 #pragma once

#endif // _MSC_VER > 1000

在ARQDlg.h中添加public变量DlgSetting setting: class CARQDlg : public CDialog {

// Construction public: DlgSetting setting; CARQDlg(CWnd* pParent = NULL); // standard constructor

工程初始化的时候要调用对话框进行设置,在ARQDlg.cpp中的OnInitDlg函数中添加代码如下:

// TODO: Add extra initialization here setting.DoModal(); return TRUE; // return TRUE unless you set the focus to a control

为了在演示过程中,也可以进行配置,双击按钮设置,添加单击事件代码: void CARQDlg::OnSetting(){ // TODO: Add your control notification handler code here setting.DoModal(); }

8.定义演示协议所需要用到的变量和函数。在CARQDlg中添加public成员变量以及函数声明:

class CARQDlg : public CDialog {

// Construction public: DlgSetting setting;//设置这个变量来设置和保存网络设置17数据 int vs;//发送帧号 int vr;//接收帧号 int queue;//队列长度 int time;//发送时间 int curr;//当前发送帧 CARQDlg(CWnd* pParent = NULL); // standard constructor //发送方处理函数 void ToBuffer();//将帧读入缓冲区 void SendFrame();//将缓冲区中的帧发送 void OnACK();//接收到ACK时的操作

void OnNAK();//接收到NAK时的操作 void OnTimeOut();//计时器超时时的操作 //接收方处理函数 void OnRecv();//接收到数据帧时候的操作 void SendACK();//发送ACK void SendNAK();//发送NAK

9.初始化状态变量,设定随机种子,在ARQDlg.cpp中的函数OnInitDlg中添加: // TODO: Add extra initialization here setting.DoModal(); SYSTEMTIME t; GetSystemTime(&t); srand(t.wMilliseconds); vs=0; vr=0; time=0; curr=0; queue=0; return TRUE; // return TRUE unless you set the focus to a control }

10.利用输入消息处理函数OnTimer实现函数间的调用,发时时间事件消息WM_TIMER

① 右键单击资源面板的文件夹,选择资源符号 ② 添加符号WM_ONACK、WM_ONNAK、WM_RECEIVE、WM_SENDACK、

WM_SENDFRAME、WM_SENDNAK、WM_TIMEOUT、WM_TOBUFFER.这些符号的值将由ClassWizard自动选择未用过的符号生成

③ 接下来用ClassWizard添加事件

WM_TIMER

④ 在Class Wizard生成的函数OnTimer中添加如下代码: void CARQDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default KillTimer(nIDEvent); switch(nIDEvent) { case WM_TIMEOUT: OnTimeOut(); break; case WM_TOBUFFER: ToBuffer(); break; case WM_SENDFRAME: SendFrame(); break;

case WM_RECEIVE: OnRecv(); break; case WM_ONACK: OnACK(); break; case WM_ONNAK: OnNAK(); break;

case WM_SENDACK: SendACK(); break; case WM_SENDNAK: SendNAK(); break; default: break; } CDialog::OnTimer(nIDEvent); }

11.在对话框资源中双击发送,产生函数OnSend并添加代码 void CARQDlg::OnSend()

{ // TODO: Add your control notification handler code here UpdateData(true); CString text; text.Format("%d个帧被送入队列\r\n",m_size); m_eveSend=text; queue=m_size; text.Format("现在队列中有%d个帧\r\n",queue); m_eveSend+=text; m_eveRecv=""; vs=vr=0; curr=0; time=0; ToBuffer(); UpdateData(false); }

12.最后实现前面定义过的函数,在ARQDlg.cpp中添加代码如下: void CARQDlg::ToBuffer() //将帧读入缓冲区 { if (queue==0) //已经全部发完 { CString text; text.Format("发送完成\r\n"); m_eveSend+=text; text.Format("发送完成,共发%d个帧,用时%dms\r\n",curr,time); m_buff=text; MessageBox(text); text.Format("平均用时%fms/帧",(float)time/(float)curr); m_buff+=text; MessageBox(text); UpdateData(false);

time=0; //重新置0

curr=0; //

}

else // 还没发完

{

curr++; //得到下面一帧

queue--;

CString text;

text.Format("当前缓冲区为第%d帧,还有%d帧要发\r\n",curr,queue);

m_buff=text;

UpdateData(false);

SendFrame(); //发送下面一帧

}

}

void CARQDlg::SendFrame() //将缓冲区中的帧发送

{

CString text;

text.Format("发送第%d帧,帧序号为%d\r\n",curr,vs);

m_eveSend+=text;

UpdateData(false);

SetTimer(WM_TIMEOUT,setting.m_timeout,NULL);//开始计时

int p=rand();

if(p%100>setting.m_missing) //So lucky!没有丢失

{

time+=setting.m_tl; //加上发送延时

SetTimer(WM_RECEIVE,setting.m_tl,NULL); //接收方收到

}

}

void CARQDlg::OnACK() //接收到ACK时的操作

{

CString text;

text.Format("接收到ACK帧,准备发下一帧\r\n");

m_eveSend +=text;

time +=setting.m_tr; //加上处理时间

vs=(vs+1)%2; //转变vs号

KillTimer(WM_TIMEOUT); //注销计时器

UpdateData(false);

SetTimer(WM_TOBUFFER,setting.m_tr,NULL);

}

void CARQDlg::OnNAK()

{

CString text;

text.Format("接收到NAK帧,准备重发\r\n");

m_eveSend+=text;

time +=setting.m_tr;

SetTimer(WM_SENDFRAME,setting.m_tr,NULL);

KillTimer(WM_TIMEOUT);

SendFrame();

UpdateData(false);

}

void CARQDlg::OnTimeOut()

{

CString text;

text.Format("计时器超时,准备重发\r\n");

m_eveSend+=text;

SendFrame();

UpdateData(false);

}

void CARQDlg::OnRecv() //接收到数据帧时候的操作

{

CString text;

text.Format("接收到第%d帧,帧序号为%d\r\n",curr,vs);

m_eveRecv+=text;

int p=rand();

if(p%100>setting.m_error&&vs==vr) //So lucky!没有损坏

{

text.Format("很幸运,%d帧完好无缺,被送往网络层\r\n",curr);

m_eveRecv+=text;

time+=setting.m_tp;

vr=(vr+1)%2;

SetTimer(WM_SENDACK,setting.m_tp,NULL);

}

else

{

if(vs==vr) //损坏,则发送NAK

{

text.Format("第%d帧损坏 \r\n",curr);

m_eveRecv+=text;

time+=setting.m_tp;

SetTimer(WM_SENDNAK,setting.m_tp,NULL); //发送NAK

}

else //序列号错误, 发ACK

{

text.Format("错误的序列号%d,该帧被丢弃 \r\n",vs);

m_eveRecv+=text;

time+=setting.m_tp;

SetTimer(WM_SENDACK,setting.m_tp,NULL); // 发送ACK

}

}

UpdateData(false);

}

void CARQDlg::SendACK()

{

CString text;

text.Format("发送ACK\r\n");

m_eveRecv+=text;

time+=setting.m_ts;

int p=rand();

if(p%100>setting.m_missing)

{

time+=setting.m_tl;

SetTimer(WM_ONACK,setting.m_tl,NULL);

}

else

{

text.Format("ACK不幸丢失 \r\n");

m_eveRecv+=text;

}

UpdateData(false);

}

void CARQDlg::SendNAK()

{

CString text;

text.Format("发送NAK\r\n");

m_eveRecv+=text;

int p=rand();

if(p%100>setting.m_missing)

{

time+=setting.m_tl;

SetTimer(WM_ONNAK,setting.m_tl,NULL);

}

else

{

text.Format("NAK不幸丢失 \r\n");

m_eveRecv+=text;

}

UpdateData(false);

}

13.编译调试,输入20,可能会得到下图结果,(根据随机数不同而不同

)

五、 实验总结

1. 通过4次试验,加上平时的练习,实验达到实验目的;

2. 通过实现协议,加深了对协议的理解;

3. 对c++6.0的功能有了进一步的认识,感觉挺好用的;

4. 当然我没学过c++,实验代码都是老师给的,函数名字都不敢改,我就严格用老师提供的ID名。

专业班号____________________ 姓 名____________________ 实验日期____________________ 指导教师____________________ 第________实验 第_______组 实验名称 ______________________________ ARQ协议实现

一、 实验目的

1.实现一个简单的自动重发协议的模拟演示 2.了解LLC层网络协议的实现方法 3.掌握MFC中的系统计时器

4.初步掌握MFC的体系结构以及消息映射方法

5.掌握VC++中AppWizard和ClassWizard的基本使用方法。 6.了解LLC层部分协议的实现步骤。 7.了解模拟的简单的重发协议的流程。 8.理解对缓冲区与滑动窗口的概念。

二、 实验环境

1.开发语言 Visual C++ 6.0 2. 软件平台 Windows XP

三、 实验原理

1、 协议及网络状态的假设

(1) 发送方将一帧发出以及帧通过物理链路传送到接收方的总时间为tl; (2) 接收方对该帧进行处理的时间为tp; (3) 接收方发ACK或NAK帧的时间为ts;

(4) 发送方收到ACK或NAK帧,进行处理的时间为tr; (5) 重发计时器的过期时间为timeout;

(6) 物理链路存在一定的丢失率以及错误率; (7) 缓冲区窗口大小为1,采用1位编码 2、发送方发送

(1) vs设0;

(2) 从缓冲区读帧,如缓冲区为空,则发送结束; (3) 发送;

(4) 设超时计数器; (5) 等待;

(6) 收到ACK,vs转成下帧的序列号,清除缓冲区,缓冲区置下帧,转(2); (7) 收到NAK,转(3); (8) 计时器超时,转(3); 3、接收方接收

(1) vr设0;

(2) 等待;

(3) 收到数据帧,正确则继续,出错则转(8); (4) 帧号对时继续;否则丢弃当前帧,转(2) (5) 将帧送网络层;

(6) Vr转成下一帧序号; (7) 发送确认帧ACK,转(2); (8) 发送NAK,转(2)

四、 实验步骤

1. 新建工程,选择

MFC AppWizard[exe]

2。单击工作区面板上的Resources,放置各种需要的控件,右击控件,选择属性,可设置控件的ID和样式。

3.对前面命名的六个资源进行属性的设置,如下表所示,选中资源->单击右键->属性->样式

资源ID

IDC_EVE_SEND

类型 EDIT BOX

样式

Multiline选中

Vertical Scroll选中 Border选中 ReadOnly选中 Static Edge选中 Multiline选中

Vertical Scroll选中 Border选中 ReadOnly选中 Static Edge选中 Border选中

Static Edge选中 Number选中 Border选中

Want Return选中 Static Edge选中

资源对应变量 CString

m_eveSend

说明

发送方的事件将显示在这里

IDC_EVE_RECV EDIT BOX

CString

m_eveRecv 接收方的事件将显示在这里

IDC_BUFF IDC_TEXT STATIC TEXT

EDIT BOX

CString m_buff int m_size

缓冲区内容将显示在这里

得到用户需要发的帧个数

IDC_SEND IDC_SETTING

BUTTON BUTTON

CButton m_send CButton m_setting

发送n个帧进行演示

配置网络

4.用ClassWizard生成的方法添加成员变量,方法如下,选择“查看”->建立类向导->Member Variables

5.在资源面板中绘制新对话框IDD_SETTING,将对话框中样式的系统菜单选项不选中,如下图

双击对话框,ClassWizard将提示需要为该对话框资源制定一个类,选择Create a new class, 并取名为DlgSetting, 并按下图,表添加成员变量,并进行初始值设定

资源ID IDC_ERROR IDC_MISSING IDC_LATANCY IDC_TIMEOUT IDC_TP IDC_TS IDC_TR IDC_OK

类型 EDIT BOX EDIT BOX EDIT BOX EDIT BOX BUTTON EDIT BOX EDIT BOX Button

资源对应变量 int m_error int m_missing int m_tl

int m_timeout int m_tp int m_ts int m_tr

CButton m_ok

说明

帧出错率 帧丢失率 发送时延(ms)

重发计时计时器过时期限(ms)

接收方处理时间(ms) 处理ACK,NAK时间(ms) 发送ACK,NAK时间(ms) 设置完成

在DlgSetting.cpp的构造函数中加初始设定: DlgSetting::DlgSetting(CWnd* pParent /*=NULL*/) : CDialog(DlgSetting::IDD, pParent) { //{{AFX_DATA_INIT(DlgSetting)

// NOTE: the ClassWizard will add member initialization here m_error = 10; m_tl = 100; m_missing = 10; m_timeout =300; m_tp = 10; m_tr = 10; m_ts = 10; //}}AFX_DATA_INIT }

6.接下来进行具体的实现,首先是模拟网络的设置,在Setting对话框资源面板中双击OK按钮,添加单击事务,实现函数OnOk()

void DlgSetting::OnOK() { // TODO: Add extra validation here UpdateData(); if(m_error>100||m_error100||m_missing

7.整个设置对话框设置好了,接下来让它生效,在ARQDlg.h的开始处添加代码:

#if !defined(AFX_ARQDLG_H__7F277C47_32BA_4297_8A25_6D20F43064B9__INCLUDED_)

#define

AFX_ARQDLG_H__7F277C47_32BA_4297_8A25_6D20F43064B9__INCLUDED_

#include "DlgSetting.h" #if _MSC_VER > 1000 #pragma once

#endif // _MSC_VER > 1000

在ARQDlg.h中添加public变量DlgSetting setting: class CARQDlg : public CDialog {

// Construction public: DlgSetting setting; CARQDlg(CWnd* pParent = NULL); // standard constructor

工程初始化的时候要调用对话框进行设置,在ARQDlg.cpp中的OnInitDlg函数中添加代码如下:

// TODO: Add extra initialization here setting.DoModal(); return TRUE; // return TRUE unless you set the focus to a control

为了在演示过程中,也可以进行配置,双击按钮设置,添加单击事件代码: void CARQDlg::OnSetting(){ // TODO: Add your control notification handler code here setting.DoModal(); }

8.定义演示协议所需要用到的变量和函数。在CARQDlg中添加public成员变量以及函数声明:

class CARQDlg : public CDialog {

// Construction public: DlgSetting setting;//设置这个变量来设置和保存网络设置17数据 int vs;//发送帧号 int vr;//接收帧号 int queue;//队列长度 int time;//发送时间 int curr;//当前发送帧 CARQDlg(CWnd* pParent = NULL); // standard constructor //发送方处理函数 void ToBuffer();//将帧读入缓冲区 void SendFrame();//将缓冲区中的帧发送 void OnACK();//接收到ACK时的操作

void OnNAK();//接收到NAK时的操作 void OnTimeOut();//计时器超时时的操作 //接收方处理函数 void OnRecv();//接收到数据帧时候的操作 void SendACK();//发送ACK void SendNAK();//发送NAK

9.初始化状态变量,设定随机种子,在ARQDlg.cpp中的函数OnInitDlg中添加: // TODO: Add extra initialization here setting.DoModal(); SYSTEMTIME t; GetSystemTime(&t); srand(t.wMilliseconds); vs=0; vr=0; time=0; curr=0; queue=0; return TRUE; // return TRUE unless you set the focus to a control }

10.利用输入消息处理函数OnTimer实现函数间的调用,发时时间事件消息WM_TIMER

① 右键单击资源面板的文件夹,选择资源符号 ② 添加符号WM_ONACK、WM_ONNAK、WM_RECEIVE、WM_SENDACK、

WM_SENDFRAME、WM_SENDNAK、WM_TIMEOUT、WM_TOBUFFER.这些符号的值将由ClassWizard自动选择未用过的符号生成

③ 接下来用ClassWizard添加事件

WM_TIMER

④ 在Class Wizard生成的函数OnTimer中添加如下代码: void CARQDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default KillTimer(nIDEvent); switch(nIDEvent) { case WM_TIMEOUT: OnTimeOut(); break; case WM_TOBUFFER: ToBuffer(); break; case WM_SENDFRAME: SendFrame(); break;

case WM_RECEIVE: OnRecv(); break; case WM_ONACK: OnACK(); break; case WM_ONNAK: OnNAK(); break;

case WM_SENDACK: SendACK(); break; case WM_SENDNAK: SendNAK(); break; default: break; } CDialog::OnTimer(nIDEvent); }

11.在对话框资源中双击发送,产生函数OnSend并添加代码 void CARQDlg::OnSend()

{ // TODO: Add your control notification handler code here UpdateData(true); CString text; text.Format("%d个帧被送入队列\r\n",m_size); m_eveSend=text; queue=m_size; text.Format("现在队列中有%d个帧\r\n",queue); m_eveSend+=text; m_eveRecv=""; vs=vr=0; curr=0; time=0; ToBuffer(); UpdateData(false); }

12.最后实现前面定义过的函数,在ARQDlg.cpp中添加代码如下: void CARQDlg::ToBuffer() //将帧读入缓冲区 { if (queue==0) //已经全部发完 { CString text; text.Format("发送完成\r\n"); m_eveSend+=text; text.Format("发送完成,共发%d个帧,用时%dms\r\n",curr,time); m_buff=text; MessageBox(text); text.Format("平均用时%fms/帧",(float)time/(float)curr); m_buff+=text; MessageBox(text); UpdateData(false);

time=0; //重新置0

curr=0; //

}

else // 还没发完

{

curr++; //得到下面一帧

queue--;

CString text;

text.Format("当前缓冲区为第%d帧,还有%d帧要发\r\n",curr,queue);

m_buff=text;

UpdateData(false);

SendFrame(); //发送下面一帧

}

}

void CARQDlg::SendFrame() //将缓冲区中的帧发送

{

CString text;

text.Format("发送第%d帧,帧序号为%d\r\n",curr,vs);

m_eveSend+=text;

UpdateData(false);

SetTimer(WM_TIMEOUT,setting.m_timeout,NULL);//开始计时

int p=rand();

if(p%100>setting.m_missing) //So lucky!没有丢失

{

time+=setting.m_tl; //加上发送延时

SetTimer(WM_RECEIVE,setting.m_tl,NULL); //接收方收到

}

}

void CARQDlg::OnACK() //接收到ACK时的操作

{

CString text;

text.Format("接收到ACK帧,准备发下一帧\r\n");

m_eveSend +=text;

time +=setting.m_tr; //加上处理时间

vs=(vs+1)%2; //转变vs号

KillTimer(WM_TIMEOUT); //注销计时器

UpdateData(false);

SetTimer(WM_TOBUFFER,setting.m_tr,NULL);

}

void CARQDlg::OnNAK()

{

CString text;

text.Format("接收到NAK帧,准备重发\r\n");

m_eveSend+=text;

time +=setting.m_tr;

SetTimer(WM_SENDFRAME,setting.m_tr,NULL);

KillTimer(WM_TIMEOUT);

SendFrame();

UpdateData(false);

}

void CARQDlg::OnTimeOut()

{

CString text;

text.Format("计时器超时,准备重发\r\n");

m_eveSend+=text;

SendFrame();

UpdateData(false);

}

void CARQDlg::OnRecv() //接收到数据帧时候的操作

{

CString text;

text.Format("接收到第%d帧,帧序号为%d\r\n",curr,vs);

m_eveRecv+=text;

int p=rand();

if(p%100>setting.m_error&&vs==vr) //So lucky!没有损坏

{

text.Format("很幸运,%d帧完好无缺,被送往网络层\r\n",curr);

m_eveRecv+=text;

time+=setting.m_tp;

vr=(vr+1)%2;

SetTimer(WM_SENDACK,setting.m_tp,NULL);

}

else

{

if(vs==vr) //损坏,则发送NAK

{

text.Format("第%d帧损坏 \r\n",curr);

m_eveRecv+=text;

time+=setting.m_tp;

SetTimer(WM_SENDNAK,setting.m_tp,NULL); //发送NAK

}

else //序列号错误, 发ACK

{

text.Format("错误的序列号%d,该帧被丢弃 \r\n",vs);

m_eveRecv+=text;

time+=setting.m_tp;

SetTimer(WM_SENDACK,setting.m_tp,NULL); // 发送ACK

}

}

UpdateData(false);

}

void CARQDlg::SendACK()

{

CString text;

text.Format("发送ACK\r\n");

m_eveRecv+=text;

time+=setting.m_ts;

int p=rand();

if(p%100>setting.m_missing)

{

time+=setting.m_tl;

SetTimer(WM_ONACK,setting.m_tl,NULL);

}

else

{

text.Format("ACK不幸丢失 \r\n");

m_eveRecv+=text;

}

UpdateData(false);

}

void CARQDlg::SendNAK()

{

CString text;

text.Format("发送NAK\r\n");

m_eveRecv+=text;

int p=rand();

if(p%100>setting.m_missing)

{

time+=setting.m_tl;

SetTimer(WM_ONNAK,setting.m_tl,NULL);

}

else

{

text.Format("NAK不幸丢失 \r\n");

m_eveRecv+=text;

}

UpdateData(false);

}

13.编译调试,输入20,可能会得到下图结果,(根据随机数不同而不同

)

五、 实验总结

1. 通过4次试验,加上平时的练习,实验达到实验目的;

2. 通过实现协议,加深了对协议的理解;

3. 对c++6.0的功能有了进一步的认识,感觉挺好用的;

4. 当然我没学过c++,实验代码都是老师给的,函数名字都不敢改,我就严格用老师提供的ID名。


相关内容

  • 深圳大学物理化学实验报告
  • 精选范文:深圳大学物理化学实验报告--燃烧热的测定--谢佳澎苏竹(共2篇) 深圳大 学物理化学实验报告实验者: 谢佳澎 苏竹 实验时间: 2000/3/5气温: 24.5 ℃ 大气压: 101.47 kpa 燃烧热的测定目的要求 一, 用氧弹热量计测定萘的燃烧热二, 明确燃烧热的定义, 了解恒压燃烧 ...

  • 测试实验报告
  • 实 实验课程:学生姓名:学 号:专业班级: 验 报 告 2014年 12 月 目 录 实验一 实验二 实验三 实验四 实验五 实验六 箔式应变片性能――单臂电桥 箔式应变片三种桥路性能比较 电涡流式传感器的静态标定 电容式传感器特性 霍尔式传感器的直流激励特性 压电加速度式传感器 南昌大学实验报告 ...

  • 成都理工大学摄影摄像实验报告
  • 成都理工大学 实验报告 课程院系班级学号 姓名 教师2012年10月制 目录 1.2.3.4.实验时必须遵守实验规则,遵照实验安排,注意安全,严格遵照时间规定. 用正确的理论指导实践.每人必须亲自动手实验,但反对盲目乱动,更不能损坏设备. 成都理工大学数字媒体技术专业实验报告 学号姓名同组姓名实验日 ...

  • 第十届全国周培源大学生力学竞赛"基础力学实验"团体赛三号通知
  • 第十届全国周培源大学生力学竞赛"基础力学实验"团体赛 第三号通知 根据第十届全国周培源大学生力学竞赛各高校个人赛的成绩排序及报名参加团体赛的情况,竞赛组委会讨论决定,获得本届参加"基础力学实验"团体赛资格的院校有: 黑龙江省 江苏省 湖北省 浙江省 江苏省 天 ...

  • 四川大学本科实验教学管理办法(修订)
  • 四 川 大 学 文 件 川大教[2006]120号 关于印发<四川大学本科实验教学管理办法 (修订)>的通知 校内各有关单位: 为了进一步规范我校的本科实验教学工作,提高教学质量,学校重新修订了<四川大学本科实验教学管理办法>,现印发给你们,请遵照执行. 附件:四川大学本科实 ...

  • 教学成果奖总结报告
  • 物理实验开放教学与创新能力培养 一.成果产生的背景与意义 大学物理实验是工科大学生进行科学实验的一门基础课程,大学物理实验是学生进行系统性专业实验的开端,是对学生进行科学素质教育的重要环节,是多元化人才的能力结构的重要组成部分. 传统的大学物理实验教学中,内容陈旧,与现实生产.生活及现代科学技术缺乏 ...

  • 2014大连理工大学无机化学实验报告
  • 大连理工大学盘锦校区无机化学实验报告 实验名称 氯化钠的提纯 班级 姓名 学号 成绩 房间号 一.实验目的 1. 2. 3. 二.实验步骤 1. 提纯 称取4 g粗食盐 2. 产品纯度检验 有关的离子方程式: 三.问题与讨论 大连理工大学盘锦校区无机化学实验报告 实验名称 硫酸铜的提纯 班级 姓名 ...

  • 香港地区在校大学生对新型护肤产品的使用和认知情况调查报告
  • 香港地区在校大学生 对新型护肤产品的使用和认知情况 调查报告 收样时间:2014年04月16日 报告编码:QM[1**********]6 报告日期:2014年07月16日 页 数:10(1) 量子医学(中国)重点实验室 Quantum Medicine(china)Laboratory 以下测试之 ...

  • 河南大学大型设备立项论证审批报告
  • 河 南 大 学 设备名称:___________ __________ 申请经费(万元): 拟使用经费科目: 实验室名称: 实验室类型: 实验室主任: 申报单位(盖章):___ _____________ 填表时间:__________ _______ 河南大学实验室与设备管理处制 填 表 说 明 ...