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

📄 protocol.cpp

📁 网络实验网络实验网络实验网络实验网络实验
💻 CPP
字号:

#include "protocol.h"
#include <stdlib.h>
#include <stdio.h>

             /*/////////////////////////////
             //       protocol.cpp        //

             /////////////////////////////*/
//函数的实现

  // 奇偶校验
  int 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;
  }

 //连接函数,返回连接到服务器是否成功
 bool connect_to_server(SOCKET &sock)
 {
	 int ret;
	 WSADATA wsaData;
	 struct sockaddr_in seraddr;
	 char inputip[40];
	 char * ip; //服务器ip地址
	 unsigned short port;  //端口
	 
	 if (WSAStartup(0x101,&wsaData))
	 {  exit(0);   } 
     
	 printf("Please input SERVER IP:");
	 scanf("%s",&inputip);

	 ip=inputip;

	 printf("Please input a PORT(1024--65536):");
	 scanf("%d",&port);

	 sock=socket(AF_INET,SOCK_STREAM,0);
	
	 seraddr.sin_family=AF_INET;
	 seraddr.sin_port=htons(port);
	 seraddr.sin_addr.S_un.S_addr=inet_addr(ip);
	 seraddr.sin_addr.S_un.S_addr=inet_addr(ip);
	
	 ret=connect(sock,(struct sockaddr *)&seraddr,sizeof(seraddr));
	
	 if (ret!=SOCKET_ERROR)
		 return true;	 
	 else
		 return false;
 }

  //从网络层取一个数据桢,读入数据放到packet中
  void from_network_layer(packet *p)
  {   	        
	  printf("please input data that being send:");
	  scanf("%s", (*p).data); 

  }
  char check_network_layer()
  {
	  char string;
	  printf("do you want to send data(Y or N)?");
	  scanf("%s",&string);
	  return string;
  }

  //从物理层取到一个桢将它拷贝到r,返回取到的数据个数
  int from_physical_layer(SOCKET sock,frame &r)
  {
	  int num;
	  num=recv(sock,(char*)&r,sizeof(r),0);
	  return num;	  
  }


   //发送一个数据
  void send_frame(SOCKET sock,frame s,int wp,int lp)
  {   
	  frame temp_frame;
	  int randnum;
	  int num1,num2,num3;
	  int i;

	  num1=wp;
	  num2=100-lp;
	  num3=num2+num1;

	  randnum=rand() % 100;

		  if( (0<=randnum)&&(randnum<num1) ) // 修改数据
		  {   
			  temp_frame=s;
			  printf("Simulate send a frame occur error!\n");
			  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))   //丢失
		  {
			  printf("Simulate frame that send lost!\n");
		  }
  } 

   //将数据发送到网络层,从接受桢中取到信息并且发送到网络层
  void to_network_layer(packet p)
  {
	  printf("The data send to NETWORK layer is:%s\n",p.data);
  }

  
   //将数据发往物理层准备传送,将数据发送出去
  void to_physical_layer(SOCKET sock,frame &s,int wp,int lp)
  {	  	 
		  printf("发送的数据是:%s\n",s.info.data);
		  printf("发送的序号是:%d\n",s.seq);
		  
	      send_frame(sock,s,wp,lp);		  	  
  }

   //等待一个事件发生,返回事件类型
  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的联系
	  FD_ZERO(&writefds); 
      FD_SET(sock,&writefds);

	  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;

  }


  

⌨️ 快捷键说明

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