要求:实现基于UDP的文件传输,客户端发送文件,服务端接受文件
服务端实现:
#include "stdafx.h"
#include "iostream"
#include "afxdialogex.h"
#include "winsock2.h"
using namespace std;
#define DEFAULT_PORT 1000//服务器监听端口
#define Length 1024*60//缓冲区大小
int main()
{
WSADATA wsadata;//结构被用来保存函数
int WsaStart = WSAStartup(MAKEWORD(1, 1), &wsadata);//返回的Windows Socket 初始化信息
if (WsaStart != 0){
return -1;
}
SOCKET Socket;
Socket = socket(AF_INET, SOCK_DGRAM, 0);
if (Socket < 0){
cout << "socket build error!" << endl;
WSACleanup();//释放资源
return -1;
}
else{
cout << "socket build success" << endl;
}
char HostName[128];//记录主机名
char *IPAddress;//记录IP地址
if (gethostname(HostName, 128) == 0)//获取主机名成功
{
struct hostent *pHost;
pHost = gethostbyname(HostName);//用域名或主机名获取IP地址
IPAddress = inet_ntoa(*(struct in_addr*)pHost->h_addr_list[0]);//取第一个地址
}
struct sockaddr_in local;//使用sockaddr_in结构指定IP地址和端口信息
local.sin_family = AF_INET;
local.sin_addr.S_un.S_addr = inet_addr(IPAddress);//将一个点分十进制的IP转换成一个长整数型 数(u_long类型),返回的整数形式是网络字节序
local.sin_port = htons(DEFAULT_PORT);//设置的端口为DEFAULT_PORT。将整型变量从主机字 节顺序转变成网络字节顺序
int BIND = bind(Socket, (sockaddr*)& local, sizeof(local));
if (BIND == SOCKET_ERROR)//将IP地址和端 口绑定到所创建的套接字上
cout << "socket build error!" << endl;
else
cout << "socket build success!" << endl;
cout << "The machine address:" << inet_ntoa(local.sin_addr) << endl;
sockaddr_in ClientAddr;//记录数据包的IP地址
int nLen = sizeof(sockaddr);
char szBuf[Length];//数据缓冲区
memset(szBuf, 0, Length);//初始化缓冲区
char path[100] = { "0" };
cout << "Please enter file path: (G:\\2.txt)" << endl;
gets(path);
FILE *file = fopen(path, "wb");
if (!file)
{
cout << "Open file failed" << endl;
return 1;
}
else
{
cout << "Waiting!!!" << endl;
}
while (1)
{
memset(szBuf, 0, Length);//清空缓冲区
int rByte = recvfrom(Socket, szBuf, Length, 0, (struct sockaddr*)&ClientAddr, &nLen);//接受文件,写入缓冲区
fwrite(szBuf, rByte, 1, file);//写入文件
if (rByte < Length)
break;
if (SOCKET_ERROR == rByte)
{
printf("recvfrom()Failed:%d\n", WSAGetLastError());
closesocket(Socket);
WSACleanup();
return -1;
}
}
fclose(file);
closesocket(Socket);
WSACleanup();
system("pause");
return 0;
}
客户端实现:
#include "stdafx.h"
#include "iostream"
#include "afxdialogex.h"
#include "winsock2.h"
using namespace std;
#define DEFAULT_PORT 1000//服务器监听端口
#define Length 1024*60
int main(){
WSADATA wsadata;
int WsaStart = WSAStartup(MAKEWORD(1, 1), &wsadata);
if (WsaStart != 0){
WSACleanup();
return -1;
}
SOCKET Socket;
Socket = socket(AF_INET, SOCK_DGRAM, 0);
if (Socket < 0){
cout<<"socket build error!"<<endl;
}
else{
cout << "socket build success!"<<endl;
}
char IPAddress[] = { "192.168.1.106" };
struct sockaddr_in local;//使用sockaddr_in结构指定IP地址和端口信息
local.sin_family = AF_INET;
local.sin_addr.S_un.S_addr = inet_addr(IPAddress);//将一个点分十进制的IP转换成一个长整数型 数(u_long类型),返回的整数形式是网络字节序
local.sin_port = htons(DEFAULT_PORT);//设置的端口为DEFAULT_PORT。将整型变量从主机字 节顺序转变成网络字节顺序
char path[100] = { "0" };
cout << "Please enter file path: (G:\\1.txt)"<<endl;
gets(path);
FILE* file = fopen(path, "rb"); // 读写二进制文件 记得 加 b
if (!file)
{
cout << "error!" << endl;
system("pause");
return 1;
}
else
{
cout << "Waiting!!!" << endl;
}
char szBuf[Length] = { 0 };
while (!feof(file))
{
memset(szBuf, 0, Length);
int RealLength = fread(szBuf, 1, Length, file);//将文件读入缓冲区
int sByte = sendto(Socket, szBuf, RealLength, 0, (sockaddr*)&local, sizeof(local));//发送文件
Sleep(10);
if (SOCKET_ERROR == sByte)
{
cout << "sendto()Failed!";
closesocket(Socket);
WSACleanup();
return -1;
}
}
fclose(file);
closesocket(Socket);
WSACleanup();
system("pause");
return 0;
}