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

📄 client.cpp

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

#include "protocol.h"
#pragma comment (lib,"ws2_32")

int main(int argc,char ** argv)
{	
     int recvnum;
	 int lost_percent,wrong_percent,time_out,repeatnum,windowsize;
	 seq_nr next_frame_to_send,ack_expected;
	 frame s,r;
	 packet buffer;
	 event_type event;
	 //fd_set readfds,writefds;
	 int temptime;
	 char checkstring;
	 int send_num[MAX_SEQ+1];

	  //定义监听接口和会话接口
	   SOCKET cli_sock;
	   bool connectser,control;
	   connectser=connect_to_server(cli_sock);
	   if(connectser)
		   printf("connect to server sucessfully!\n");
	   else
	   {
		 printf("connect to server error!\n"); 
		 return 0;
	   }
	   for(int i=0;i<(MAX_SEQ+1);i++) 
		send_num[i]=0;

	   RecvQueue rq;//接收数据的缓冲区
	   rq.recvbuffer=(Recvbuffer *) malloc((MAX_SEQ+1)*sizeof(Recvbuffer));//初始化
	   rq.rfront=rq.rrear=0;

	   SendQueue sq;//发送数据的缓冲区
	   sq.sendbuffer=(Sendbuffer *) malloc((MAX_SEQ+1)*sizeof(Sendbuffer));
	   sq.sfront=sq.srear=0;
	   sq.sendbuffer[sq.srear].time=0;
	   while((sq.srear+1)%(MAX_SEQ+1)!=sq.sfront)
	   {
		   sq.srear=(sq.srear+1)%(MAX_SEQ+1);
          sq.sendbuffer[sq.srear].time=0;
	   }

       sq.sfront=sq.srear=0;

      do
	  {
          printf("\r\n");
	      printf("请输入传输数据的丢失率(%%):");
	        scanf("%d",&lost_percent);
	      printf("请输入传输数据的出错率(%%):");
	        scanf("%d",&wrong_percent);
	  } while((lost_percent+wrong_percent)>=100);

		  printf("\r\n");		  
		  printf("传输数据的正确率为(%%):%d",100-lost_percent-wrong_percent);
          printf("\r\n");
		  printf("请输入窗口的大小(1-7):");
		    scanf("%d",&windowsize);
		  printf("\r\n");
	      printf("请输入超时时间(秒)(数值不能为0):");  
	        scanf("%d",&time_out);
		  printf("请输入重传的次数:");
	        scanf("%d",&repeatnum);

         SYSTEMTIME st;
    
	     next_frame_to_send=0;
	     ack_expected=1;
	     control=true;
	 	 
	 do
	 {
		wait_for_event(cli_sock,event);

		if(event==can_write)
		{   
		     
	       if(((sq.srear-sq.sfront+MAX_SEQ+1)%(MAX_SEQ+1))<windowsize)
		   {  
			   checkstring=check_network_layer();
               if(checkstring=='Y'||checkstring=='y')
			   {
			  
					from_network_layer(&buffer);
			        s.kind=data;
		            s.seq=next_frame_to_send;		        
		            s.info=buffer;  
		            s.checksum=checksum_mat(s.kind,s.seq,s.info);
				  
			        GetSystemTime(&st);
                    //把发送的数据放到发送缓冲区
                    sq.sendbuffer[sq.srear].isack=false;
	                sq.sendbuffer[sq.srear].sendframe=s;
	                sq.sendbuffer[sq.srear].time=st.wSecond;
	                printf("the time is %d\n",sq.sendbuffer[sq.srear].time);
	                sq.srear=(sq.srear+1)%(MAX_SEQ+1);
			        inc(next_frame_to_send);
			        to_physical_layer(cli_sock,s,wrong_percent,lost_percent);
					send_num[sq.sendbuffer[sq.sfront].sendframe.seq]++;
			   }
			
			   if(checkstring=='1')
			   {
					printf("the sender has send the data successfully!And will be disconnect with server!!\n");
                    control=false;
					break;
			   }
			   
		   }
		}
	       
      if (event==frame_arrival) 
	  {   
			 printf("有数据到达!\n");
			 recvnum=from_physical_layer(cli_sock,r);

             if ((rq.rrear+1)%(MAX_SEQ+1)==rq.rfront)//队列已满
			 {
				 printf("the recvbuffer is full!\n");
			 }

			 rq.recvbuffer[rq.rrear].recvframe=r;
			 rq.recvbuffer[rq.rrear].ischeck=false;
			 rq.rrear=(rq.rrear+1)%(MAX_SEQ+1);
			 printf("the recvive buffer is %d\n",(rq.rrear-rq.rfront+MAX_SEQ+1)%(MAX_SEQ+1));

		   //处理收到的各帧  
		    while((rq.rfront!=rq.rrear)&&(!rq.recvbuffer[rq.rfront].ischeck))
			{   
			    if(rq.recvbuffer[rq.rfront].recvframe.ack==ack_expected)
				{ 				     
				    printf("A ACK arrival!\n");
				    printf("The number of the ACK is:%d\n",rq.recvbuffer[rq.rfront].recvframe.ack);
                    rq.recvbuffer[rq.rfront].ischeck=true;
				    sq.sendbuffer[sq.sfront].isack=true;
				    sq.sendbuffer[sq.sfront].time=0;  //收到确认帧后,计时器停止计时
                    inc(ack_expected);
					send_num[sq.sendbuffer[sq.sfront].sendframe.seq]=0;
				    rq.rfront=(rq.rfront+1)%(MAX_SEQ+1);
					sq.sfront=(sq.sfront+1)%(MAX_SEQ+1);
					
				}
			    else
				{
				  printf("the ack we received is %d\n",rq.recvbuffer[rq.rfront].recvframe.ack);
				  //send_num[sq.sendbuffer[sq.sfront].sendframe.seq]=0;
				  rq.rfront=(rq.rfront+1)%(MAX_SEQ+1);
				  //send_num[sq.sendbuffer[sq.sfront].sendframe.seq]++;
				}
			 } 
	  }

                    
	  //处理发生超时的帧
	  GetSystemTime(&st);
	  temptime=st.wSecond;

	   if(sq.sendbuffer[sq.sfront].time>temptime)
	   {
	   temptime=temptime+60;
	   }

	if((temptime-sq.sendbuffer[sq.sfront].time)>time_out&&(sq.sendbuffer[sq.sfront].time!=0))
	{
         printf("the %d occut time out event\n",sq.sendbuffer[sq.sfront].sendframe.seq);
		 //计时器置为0
		 sq.stemp=sq.sfront;
		 while(sq.stemp!=sq.srear)
		{
			sq.sendbuffer[sq.stemp].time=0;
			sq.stemp=(sq.stemp+1)%(MAX_SEQ+1);
		}

		 if(send_num[sq.sendbuffer[sq.sfront].sendframe.seq]>repeatnum)
			 {
                printf("the send_num is bigger than repeatnum! The data send will be stop!\n");
			    shutdown(cli_sock,1);
			    break;
			 }
	    //超时重传数据
         sq.stemp=sq.sfront;
		 ack_expected=sq.sendbuffer[sq.sfront].sendframe.seq;////
		 inc(ack_expected);////
		 while(sq.stemp!=sq.srear)
		 {  
			 send_num[sq.sendbuffer[sq.sfront].sendframe.seq]++;
             GetSystemTime(&st);
			 sq.sendbuffer[sq.stemp].time=st.wSecond;
			 printf("resend data! the read time!\n");
			 to_physical_layer(cli_sock,sq.sendbuffer[sq.stemp].sendframe,wrong_percent,lost_percent);
             sq.stemp=(sq.stemp+1)%(MAX_SEQ+1); 
		 }
	}
		 
     }while(control);
   
	shutdown(cli_sock,1);

    WSACleanup();
	return 0;
}

⌨️ 快捷键说明

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