📄 client.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 + -