📄 protocol.cpp
字号:
#include "protocol.h"
/*/////////////////////////////
// protocol.cpp //
/////////////////////////////*/
//函数的实现
//检查效验和,返回检查的结果
bool examine_checksum(frame r)
{
int num;
int checkbit;
num=1;
//对包中的数据信息先进行奇偶校验,
while (r.info.data[num]!='\0')
{
r.info.data[num]=(r.info.data[num])^(r.info.data[num-1]);
num++;
}
//得出包中数据信息的校验位
checkbit=r.info.data[num-1];
//再把帧的类型和序号与校验位异或,最后得出这个帧的一个校验位
checkbit=checkbit^(r.kind);
checkbit=checkbit^(r.seq);
//查看校验结果是否正确
if (checkbit==r.checksum)
return true;
else
return false;
}//end of examine_checksum
//从物理层取到一个桢将它拷贝到r,返回取到的数据个数
int 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 send_frame(SOCKET sock,frame s)
{
send(sock,(char*)&s,sizeof(s),0);
} //end of send_frame
//连接函数,返回监听和接收是否成功
bool set_server(SOCKET * listensock,SOCKET * sessionsock)
{
WSADATA wsaData;
int len;
struct sockaddr_in seraddr,cliaddr;
char name[255]; //主机名
char * ip; //主机ip
PHOSTENT hostinfo;
unsigned short port; //端口
if (WSAStartup(0x101,&wsaData))
{
printf("WSAStartup faile!\n");
exit(0);
}
(*listensock)=socket(AF_INET,SOCK_STREAM,0);
//获取本机IP地址
if( gethostname ( name, sizeof(name)) == 0) //返回标准的本机主机名
{
if((hostinfo = gethostbyname(name)) != NULL) //根据主机名返回主机信息
{
ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
printf("The host IP is:%s\n",ip); //输出本机的Ip地址
}
}
//输入端口号
printf("Please input a PORT(1024--65536):");
scanf("%d",&port);
seraddr.sin_family=AF_INET;
seraddr.sin_port=htons(port);
seraddr.sin_addr.S_un.S_addr=inet_addr(ip);
bind(*listensock,(sockaddr *)&seraddr,sizeof(seraddr));
listen(*listensock,3);
printf("Begin listening...\n");
len=sizeof(cliaddr);
(*sessionsock)=accept(*listensock,(sockaddr *)&cliaddr,&len);
if ((*sessionsock)!=SOCKET_ERROR)
{
printf("connect from %s:%d\n",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));
return true;
}
else
return false;
} //end of set_server
//将数据发送到网络层
void to_network_layer(packet p)
{
char buff[1500];
int num;
printf("The data send to NETWORK layer is:%s\n",p.data);
num=0;
sprintf( buff,"%s\n",p.data );
printf("%s","0x");
while(buff[num]!='\0')
{
printf("%x ",buff[num]);
num++;
}
printf("\r\n");
}
//end of to_network_layer
//将数据发往物理层传送
void to_physical_layer(SOCKET sock,frame &s)
{
send_frame(sock,s);
}
//end of to_physical_layer
//等待一个事件发生,返回事件类型
void 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的联系。
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 + -