⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c++arqmoni.txt

📁 C++ ARQ模拟
💻 TXT
字号:
void CPro7Dlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	switch(nIDEvent)
	{
	case ID_SEND_TIMER: //发送定时器被触发
		if(m_sType==0)//当前的发送模式是正常发送模式 
		{
			if((isNetEnable)&&(isToResend==-1)&&(!StopSend))
NetReady();//当网络层可用,没有要重发的帧,而且不在暂停状态,产生一个新的帧,并且发送
			else{
				if(isToResend!=-1)//有需要重发的帧
				Resend();
			}
			if(nbuffer<m_SendWnd)//检验发送窗口是否已满,以此决定打开或者关闭网络层
				isNetEnable=1;
			else
				isNetEnable=0;
		}
		if(m_sType==1)//当前的发送模式是错序发送模式
		{

			if(waitsend[point]!=-1)//按错序发送
			{
				SendFrame(waitsend[point]);
				ShowFrame(waitsend[point]);
				point++;
			}
			else 
			{
				if(timerpoint<m_SendWnd) //错序发送完毕后依次打开重发定时器
					start_timer(timerpoint++);
else//重发定时器全部打开后,这一批错序发送已经完毕,重新转入到正常的发送模式
					m_sType=0;
			}
		}
			break;
	case ID_FRAME_TIMER1://重发定时器触发,记录下要重发的帧序号
		isToResend=0;
		break;
	case ID_FRAME_TIMER2:
		isToResend=1;
		break;
	case ID_FRAME_TIMER3:
		isToResend=2;
		break;
	case ID_FRAME_TIMER4:
		isToResend=3;
		break;
	case ID_FRAME_TIMER5:
		isToResend=4;
		break;
	case ID_FRAME_TIMER6:
		isToResend=5;
		break;
	case ID_FRAME_TIMER7:
		isToResend=6;
		break;
	case ID_FRAME_TIMER8:
		isToResend=7;
		break;
	}
	ShowWndStatus();//更新界面显示的滑动窗口
	CDialog::OnTimer(nIDEvent);
}

void CPro7Dlg::ReceiveFrame()
{
	CString fk;//接收消息
	CString sq;
	CString in;
	CString ck;
	CString t;
	CString str;
	TCHAR temp[10]="\0";
    char  buf[5][255];
	m_recv.Receive(buf,1275);

	fk.Format("%s",buf[0]);
	sq.Format("%s",buf[1]);
	in.Format("%s",buf[2]);
	ck.Format("%s",buf[3]);
	t.Format("%s",buf[4]);

	if(ck=="0")//ack或nak正常的到达
	{

		AddItem(nIndex,0,fk);//显示消息
		AddItem(nIndex,1,sq);
		AddItem(nIndex,2,in);
		if(fk=="ack")
			AddItem(nIndex,3,"ack arrived");
		else
			AddItem(nIndex,3,"nak arrived");
		AddItem(nIndex++,4,t);

if(fk=="nak"&&between(ack_expected,atoi(sq),frame_to_send))//如果收到nak且序列号在窗口中,用变量记录下来,等待下一个时隙重发。
	{
		isToResend=atoi(sq);
	}
	else
	{
		if(fk=="ack")//收到确认,滑动窗口
			{
				while(between(ack_expected,atoi(sq),frame_to_send))
				{
					nbuffer=nbuffer-1;
					stop_timer(ack_expected%m_SendWnd);
					inc(ack_expected);
				}
			}
	}
	}

	else
		if(ck=="2")//确认消息在信道中丢失了
		{
			AddItem(nIndex,0,fk);
			AddItem(nIndex,1,sq);
			AddItem(nIndex,2,in);
			AddItem(nIndex,3,"ack or nak lost");
			AddItem(nIndex++,4,t);
		}
ShowWndStatus();
}
接收方:
void CPro6Dlg::ReceiveFrame()
{
if(isReady)//当前处在可以接收数据包的状态
{	
		CString fk;
		CString sq;
		CString in;
		CString ck;
		CString t;
		CString str;
		TCHAR temp[10]="\0";
    	char  buf[5][255];
		m_recv.Receive(buf,1275);//接收数据包

		fk.Format("%s",buf[0]);
		sq.Format("%s",buf[1]);
		in.Format("%s",buf[2]);
		ck.Format("%s",buf[3]);
		t.Format("%s",buf[4]);
		isReady=FALSE;

		AddItem(nIndex,0,fk);//显示数据包
		AddItem(nIndex,1,sq);
		AddItem(nIndex,2,in);
		AddItem(nIndex,3,ck);
		AddItem(nIndex,4,t);
		nIndex++;

		if(ck=="0")//如果到达的是一个完好的数据包
		{

			if(frame_expected!=atoi(sq)&&no_nak)
sendnak();//不是当前期望得到的数据包,有理由怀疑那一帧已经丢失或者损坏,所以要求重传
			else//否则启动辅助定时器
				start_ack_timer();

if(between(frame_expected,atoi(sq),too_far)&&//如果该帧的序列号在接收窗口内并且以前没有收到过该帧
(arrived[atoi(sq)%m_RecvWnd]==FALSE))
			{
				arrived[atoi(sq)%m_RecvWnd]=TRUE;//接收数据包
while(arrived[frame_expected%m_RecvWnd])//发现有按序到来的数据包则按需提交给网络层
				{
					CString str;
					str.Format("%d",frame_expected);
					str+=" write to disk";
AddItem(nIndex++,0,str);//由于是模拟协议,这里并没有真的提交,只是显示一下而已,但是只要将这四行代码换成写入硬盘的代码就可以实现。
no_nak=TRUE;//frame_expected已经提交,对下一个序列号的帧,显然没有发送过nak
					arrived[frame_expected%m_RecvWnd]=FALSE;
					inc(frame_expected);//滑动接收窗口
					inc(too_far);
					start_ack_timer();//启动辅助定时器
				}
			}
	} 
		if(ck=="1")//接收到一个错误的帧,如果接受到被丢弃的帧,不做任何处理
		{
			if(no_nak) sendnak();
		}
}
ShowWndStatus();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -