前言:
TCP版本请参考本人博客:http://blog.csdn.net/luchengtao11/article/details/71012580
本文所述代码工程托管在Github:https://github.com/Wuchenwcf/MyCode/tree/master/C%2B%2B/Socket
本文实现以下功能:
在客户端,用户选择本地的某个文件,并发送到服务器端。
在服务器端,接收客户端传输的数据流,并按IP 地址保存在服务器端(文
件名重复的,可以覆盖)。
如果传输过程中服务器端发现客户端断开,服务器端应删除文件,并在屏幕
上提示,如“IP:1.2.3.4 发来abcd.txt 文件过程中失去连接。”。如果客户端发
现服务器端不工作,客户端应有提示“服务器1.2.3.5:62345 失去连接”。
一、UDP传输流程图
二、代码实现
1.1.FileHelper用来进行与文件相关的操作
#include
#include
#include
#include
#pragma comment(lib,"ws2_32.lib")
class FileHelper
{
private:
FILE *f;
char path_buffer[_MAX_PATH];
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
public:
FILE * selectfile()
{
printf("请输入要传送的文件名\n");
scanf("%s",path_buffer);
if (f=fopen(path_buffer,"rb"))
{
printf("文件打开成功\n");
return f;
}
else
{
printf("文件不存在,请重新输入\n");
return selectfile();
}
}
char * getFileName()
{
_splitpath(path_buffer, drive, dir, fname, ext);
return strcat(fname, ext);
}
FILE * createFile(char *name)
{
remove(name);
if (f = fopen(name, "ab"))
{
printf("文件创建成功\n");
}
else
{
printf("文件创建失败\n");
}
return f;
}
bool createDir(char *dir)
{
char head[MAX_PATH] = "md ";
return system(strcat(head, dir));
}
};
#pragma comment(lib,"Ws2_32.lib")
#include
#include
#include
#include
#include"FileHelper.h"
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
char sendData[BUFSIZ]="ÄãºÃ£¡\n";
char beginData[BUFSIZ]="Begin\n";
char overData[BUFSIZ]="Over\n";
char Filename[BUFSIZ]={};
FileHelper fh;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error: %d\n", err);
return 1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return 1;
}
SOCKADDR_IN addrServ;
addrServ.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrServ.sin_family=AF_INET;
addrServ.sin_port=htons(4999);
while (true)
{
SOCKET socketClient=socket(AF_INET,SOCK_DGRAM,0);
FILE *f=fh.selectfile();
sendto(socketClient,beginData,BUFSIZ,0,(SOCKADDR*)&addrServ,sizeof(SOCKADDR));
strcpy(Filename,fh.getFileName());
sendto(socketClient,Filename,BUFSIZ,0,(SOCKADDR*)&addrServ,sizeof(SOCKADDR));
int count=0;
int sum=0;
while ((count=fread(sendData,1,BUFSIZ,f))>0)
{
Sleep(1);
printf("%d\n",sum+=count);
sendto(socketClient,sendData,BUFSIZ,0,(SOCKADDR*)&addrServ,sizeof(SOCKADDR));
}
sendto(socketClient,overData,BUFSIZ,0,(SOCKADDR*)&addrServ,sizeof(SOCKADDR));
closesocket(socketClient);
}
WSACleanup();
return 0;
}
3.Servet端
#pragma comment(lib,"Ws2_32.lib")
#include
#include
#include
#include
#include "FileHelper.h"
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
FileHelper fh;
int err;
wVersionRequested=MAKEWORD(2,2);
err=WSAStartup(wVersionRequested,&wsaData);
if (err!=0)
{
printf("WSAStartup failed with error:%d\n",err);
return -1;
}
if (LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return -1;
}
SOCKET socketServer=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
SOCKADDR_IN addrServ;
addrServ.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//指定0.0.0.0地址,表示任意地址
addrServ.sin_family=AF_INET;//表示IPv4的套接字类型
addrServ.sin_port=htons(4999);
bind(socketServer,(SOCKADDR*)&addrServ,sizeof(SOCKADDR));
SOCKADDR_IN addrClient;
int length=sizeof(SOCKADDR);
char recvBuf[BUFSIZ]={};
int rev=0;
while (true)
{
DWORD TIME_OUT=10;
char sendData[BUFSIZ]="你好!\n";
char beginData[BUFSIZ]="Begin\n";
char overData[BUFSIZ]="Over\n";
char Filename[BUFSIZ]={};
char ClientAddr[BUFSIZ]={};
char FromName[BUFSIZ]={};
FILE *f=NULL;
if(err=setsockopt(socketServer,SOL_SOCKET,SO_SNDTIMEO,(char *)&TIME_OUT,sizeof(TIME_OUT)))
{
printf("失败!\n");
};
printf("%d\n",err);
recvfrom(socketServer,recvBuf,BUFSIZ,0,(SOCKADDR*)&addrClient,&length);
if (strcmp(recvBuf,beginData)==0)
{
recvfrom(socketServer,recvBuf,BUFSIZ,0,(SOCKADDR*)&addrClient,&length);
strcpy(ClientAddr,inet_ntoa(addrClient.sin_addr));
strcpy(FromName,recvBuf);
fh.createDir(ClientAddr);
strcpy(Filename,ClientAddr);
strcat(Filename,"\\");
strcat(Filename,recvBuf);
f=fh.createFile(Filename);
}
int sum=0;
while((rev=recvfrom(socketServer,recvBuf,BUFSIZ,0,(SOCKADDR*)&addrClient,&length))>0)
{
if (strcmp(overData,recvBuf)==0)
{
printf("文件%s传输成功!\n",FromName);
fclose(f);
break;
}
// printf(recvBuf);
fwrite(recvBuf,1,rev,f);
printf("%db\n",sum+=rev);
}
if (rev<0||strcmp(overData,recvBuf)!=0)
{
printf("IP:%s发来的%s传输过程中失去连接\n",addrClient,FromName);
fclose(f);
remove(Filename);
}
}
closesocket(socketServer);
WSACleanup();
return 0;
}