📄 protocol.cpp
字号:
// protocol.cpp: implementation of the Cprotocol class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "client.h"
#include "protocol.h"
#include "FromNetworkDlg.h"
#include "Checknetworklayer.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Cprotocol::Cprotocol()
{
}
Cprotocol::~Cprotocol()
{
}
// 求校验和,返回校验和
int Cprotocol::checksum_mat(int framekind,int frameseq,packet p)
{
int num;
int checkbit;
num=1;
//对包中的数据信息先进行奇偶校验,
while (p.data[num]!='\0')
{
p.data[num]=(p.data[num])^(p.data[num-1]);
num++;
}
//得出包中数据信息的校验位
checkbit=p.data[num-1];
//再把帧的类型和序号与校验位异或,最后得出这个帧的一个校验位
checkbit=checkbit^framekind;
checkbit=checkbit^frameseq;
return checkbit;
} //end of checksum_mat
//从网络层取一个数据帧,读入数据放到packet中
void Cprotocol::from_network_layer(packet * p)
{
CFromNetworkDlg fromnetworkDlg;
CString temp;
int num,i;
fromnetworkDlg.DoModal();
temp=fromnetworkDlg.m_sInPut;
num=temp.GetLength();
for(i=0;i<num;i++)
(*p).data[i]=temp[i];
(*p).data[i]='\0';
}//end of from_network_layer
CString Cprotocol::check_network_layer()
{
CChecknetworklayer checknetworklayer;
CString string;
checknetworklayer.DoModal();
string=checknetworklayer.m_checkinput;
return string;
}
//从物理层取到一个帧
int Cprotocol::from_physical_layer(SOCKET sock,frame &r)
{
int num;
num=recv(sock,(char *)&r,sizeof(r),0);
return num;
}// end of from_physical_layer
//发送一个数据帧
void Cprotocol::send_frame(SOCKET sock,frame s,int wp,int lp)
{
CString addstr;
frame temp_frame;
int randnum;
int num1,num2,num3;
int i;
num1=wp;
num2=100-lp;
num3=num2+num1;
randnum=rand() % 100;
switch(s.kind)
{
case data:
if( (0<=randnum)&&(randnum<num1) ) //[0,(1-a)/2) 修改数据
{
temp_frame=s;
AfxMessageBox("Simulate frame occur error!");
i=0;
while(temp_frame.info.data[i]!='\0')
{
if ( (rand() % 3)==0 )
temp_frame.info.data[i]=(char)((int)(temp_frame.info.data[i])+1);
i++;
}
send(sock,(char*)&temp_frame,sizeof(temp_frame),0);
}
else if( (num1<=randnum)&&(randnum<num2) ) //正确
{
send(sock,(char*)&s,sizeof(s),0);
}
else if ((num2<=randnum)&&(randnum<num3)) //丢失
{
AfxMessageBox("Simulate frame that send lost!");
}
break;
}//end switch
} //end of send_frame
//将数据发送到网络层,从接收帧中取到信息并且发送到网络层
CString Cprotocol::to_network_layer(packet p)
{
CString tempstr;
tempstr.Format("%s",p.data );
return tempstr;
}
//end of to_network_layer
//将数据发往物理层准备传送,将数据发送出去
void Cprotocol::to_physical_layer(SOCKET sock,frame &s,int wp,int lp)
{
send_frame(sock,s,wp,lp);
}
//end of to_physical_layer
//等待一个事件发生,返回事件类型
void Cprotocol::wait_for_event(SOCKET sock,event_type &event)
{
fd_set readfds,writefds;
struct timeval tv;
FD_ZERO(&readfds);//清空fdset与所有文件句柄的联系。
FD_SET(sock,&readfds);//建立文件句柄clisock与fdR的联系。
FD_ZERO(&writefds);//清空fdset与所有文件句柄的联系。
FD_SET(sock,&writefds);//建立文件句柄clisock与fdR的联系
tv.tv_sec=0;
tv.tv_usec=0;
select(sock+1, &readfds, &writefds, NULL,NULL);
if (FD_ISSET(sock, &readfds))
event=frame_arrival;
else
event=can_write;
}//end of wait_for_event
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -