📄 receiver.cpp
字号:
// receiver.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <WinSock2.h>
#include "../header/ARQ.h"
#include "../header/Exception.h"
// 服务器端口
#define SERVER_PORT 2280
#pragma comment(lib,"ws2_32.lib")//设置link时的lib库
using namespace std;
SOCKET PrimaryUDP;
char FileSavePath[MAX_PATH];
void InitWinSock()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
throw Exception("Windows sockets 2.2 startup unsuccessful");
}
else{
printf("Using %s (Status: %s)\n",
wsaData.szDescription, wsaData.szSystemStatus);
printf("with API versions %d.%d to %d.%d\n\n",
LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion),
LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));
}
}
void mksock(int type)
{
PrimaryUDP = socket(AF_INET, type, 0);
if (PrimaryUDP < 0)
{
throw Exception("create socket error");
}
}
void BindSock()
{
sockaddr_in sin;
sin.sin_addr.S_un.S_addr = INADDR_ANY;
sin.sin_family = AF_INET;
sin.sin_port = htons(SERVER_PORT);
if (bind(PrimaryUDP, (struct sockaddr*)&sin, sizeof(sin)) < 0)
throw Exception("bind error");
}
DWORD WINAPI ARecv(LPVOID lpParam)
{
FILE * file = NULL;
sockaddr_in remote;
int sinlen = sizeof(remote);
BSC buffer,bsc;
bsc.header = STX;bsc.tail = ETX;
memset(bsc.data, 0, MAXBSCLENGTH);
int iread = 0;
unsigned long dwReceived = 0;
bool number = true;//发送方的数据开始发送时的序号设为0,为了判断是不是第一次一段数据,所以这里标为1
while (true)
{
iread = recvfrom(PrimaryUDP,(char*)&buffer,sizeof(buffer),0,(sockaddr*)&remote,&sinlen);
if (SOCKET_ERROR == iread || buffer.header != STX || buffer.tail != ETX)
{
// 数据错误,发送负应答
cout<<"received a error data"<<endl;
bsc.bcc = NAK;bsc.number=false;//number这时没有实际的意义
sendto(PrimaryUDP,(char*)&bsc,sizeof(bsc),0,(sockaddr*)&remote,sinlen);
continue;
}
if (buffer.number == number)
{
// 重复收到数据,发送应答消息
cout<<"received a repeat data"<<endl;
bsc.bcc = ACK;
bsc.number = buffer.number;
sendto(PrimaryUDP,(char*)&bsc,sizeof(bsc),0,(sockaddr*)&remote,sinlen);
continue;
}
switch(buffer.bcc)
{
case ENQ:
{
number = !number;//准备接收下一段数据
// 文件请求
cout<<"received a file request message,filename:"<<buffer.data<<endl;
// 打开文件
if(strcmp((FileSavePath+strlen(FileSavePath)-1),"\\")!=0)
strcat(FileSavePath,"\\");
strcat(FileSavePath,buffer.data);
if((file = fopen(FileSavePath, "ab")) == NULL)
{
cout<<"file open failed"<<endl;
return -1;
}
break;
}
case SYN:
{
number = !number;
// 文字发送中
int i =0;
if((i=fwrite(buffer.data, sizeof(char), sizeof(buffer.data), file)) <= 0)
{
cout << "write failed" << endl;
return -1;
}
dwReceived += i;
cout<<"write:"<<i<<"\treceived:"<<sizeof(buffer.data)<<endl;
break;
}
case EOT:
{
number = !number;
// 文件发送完毕
cout<<"file received completely,save path:"<<FileSavePath<<",received size:"<<dwReceived<<endl;
fclose(file);
break;
}
default:
{
// 数据错误,发送负应答
bsc.bcc = NAK;bsc.number=false;
sendto(PrimaryUDP,(char*)&bsc,sizeof(bsc),0,(sockaddr*)&remote,sinlen);
continue;
break;
}
}
// 发送应答消息
bsc.bcc = ACK;
bsc.number = buffer.number;
sendto(PrimaryUDP,(char*)&bsc,sizeof(bsc),0,(sockaddr*)&remote,sinlen);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
InitWinSock();
mksock(SOCK_DGRAM);
BindSock();
CreateThread(NULL, 0, ARecv, NULL, 0, NULL);
cout<<"Please input the file save path:";
cin>>FileSavePath;
cout<<"receiver start succeed"<<endl;
getchar();
getchar();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -