面向无连接UDP协议的文件传输
花了差不多一天的时间,参照郑老师上课的代码自己摸索出来的udp协议文件传输。具体功能如下
1.客户端向服务器发送一个想要下载的文件名
2.服务器接收这个文件名,打开相应的文件,读取文件内容,再发送回客户端,文件发送的完成用一个长度为0的udp报文段作为标志
3.客户端将接收的数据写入本地指定的文件名中。
客户端代码:
//客户端
#include<stdio.h>
#include<string.h>
#include<Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define MAX_BUF 65536
int main()
{
WSAData wsaData;
int err=WSAStartup(WINSOCK_VERSION,&wsaData);
if(0!=err)
{
return -1;
}
SOCKET sock;
sock=socket(AF_INET,SOCK_DGRAM,0);
if(INVALID_SOCKET==sock)
{
printf("socket()Failed:%d\n",WSAGetLastError());
WSACleanup();
return -1;
}
char data[]="Hello World!";
char dest_ip[]="192.168.1.104 "; //目的IP
unsigned short dest_port=20000;//目的端口
sockaddr_in RemoteAddr;
RemoteAddr.sin_family = AF_INET;
RemoteAddr.sin_port = htons(dest_port);
RemoteAddr.sin_addr.s_addr=inet_addr(dest_ip);
char rbuf[MAX_BUF];
memset(rbuf,0,MAX_BUF);
int RemoteLen=sizeof(RemoteAddr);
char path[100]={"0"};
char name[100]={"0"};
printf("发送文件名\n");
gets(path);
FILE *fp=fopen(path,"wb");
if(!fp)
{
printf("打开文件失败!");
return 1;
}
else
{
printf("文件已打开,等待传输\n");
}
while(1)
{
sendto(sock,path,strlen(path),0,(sockaddr*)&RemoteAddr,sizeof(RemoteAddr));
memset(rbuf,0,1024);
int sByte = sendto(sock,rbuf,strlen(rbuf),0,(sockaddr*)&RemoteAddr,sizeof(RemoteAddr));
if(SOCKET_ERROR==sByte)
{
printf("sendto()Failed:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
recvfrom(sock,name,1024,0,(sockaddr*)&RemoteAddr,&RemoteLen);
memset(rbuf,0,1024);
int rByte=recvfrom(sock,rbuf,1024,0,(sockaddr*)&RemoteAddr,&RemoteLen);
if(SOCKET_ERROR==rByte)
{
printf("recvfrom()Failed:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
fwrite(rbuf,1,strlen(rbuf),fp);
fseek(fp,0,2);
printf("写入的文件内容为:\n %s\n",rbuf);
}
fclose(fp);
closesocket(sock);
WSACleanup();
return 0;
}
服务端代码:
//服务端
#include<stdio.h>
#include<string.h>
#include<Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
int main()
{
WSAData wsaData;
int err=WSAStartup(WINSOCK_VERSION,&wsaData);
if(0!=err)
{
return -1;
}
SOCKET sock;
sock=socket(AF_INET,SOCK_DGRAM,0);
if(INVALID_SOCKET==sock)
{
printf("socket()Failed:%d\n",WSAGetLastError());
WSACleanup();
return -1;
}
sockaddr_in LocalAddr;
LocalAddr.sin_family=AF_INET;
LocalAddr.sin_port=htons(20000);
LocalAddr.sin_addr.s_addr=htonl(INADDR_ANY);
err=bind(sock,(sockaddr*)&LocalAddr,sizeof(LocalAddr));
if(SOCKET_ERROR==err)
{
printf("bind()Failed:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
sockaddr_in RemoteAddr;
int RemoteLen = sizeof(RemoteAddr);
char path[100]={"0"};
char name[100]={"0"};
while(1)
{
printf("请输入文件路径\n");
gets(path);
FILE* fp=fopen(path,"rb"); // 读写二进制文件 记得 加 b
if(!fp)
{
printf("error!");
return 1;
}
else
{
printf("文件已经打开,等待传输...\n");
}
char rbuf[1024]={0};
while(1)
{
recvfrom(sock,name,1024,0,(sockaddr*)&RemoteAddr,&RemoteLen);
printf("文件名字为:\n %s\n",name);
memset(rbuf,0,1024);
int rByte=recvfrom(sock,rbuf,1024,0,(sockaddr*)&RemoteAddr,&RemoteLen);
if(SOCKET_ERROR==rByte)
{
printf("recvfrom()Failed:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
while(!feof(fp))
{
sendto(sock,path,strlen(path),0,(sockaddr*)&RemoteAddr,sizeof(RemoteAddr));
memset(rbuf,0,1024);
fread(rbuf,1,1024,fp);
int sByte=sendto(sock,rbuf,strlen(rbuf),0,(sockaddr*)&RemoteAddr,sizeof(RemoteAddr));
if(SOCKET_ERROR==sByte)
{
printf("sendto()Failed:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
}
}
fclose(fp);
}
closesocket(sock);
WSACleanup();
return 0;
}