Windows Socket编程之UDP实现大文件的传输

来源:互联网 发布:微控触摸屏软件 编辑:程序博客网 时间:2024/05/10 16:25

前言:

TCP版本请参考本人博客:http://blog.csdn.net/luchengtao11/article/details/71012580

本文所述代码工程托管在Github:https://github.com/Wuchenwcf/MyCode/tree/master/Socket

本文实现以下功能:

在客户端,用户选择本地的某个文件,并发送到服务器端。
在服务器端,接收客户端传输的数据流,并按IP 地址保存在服务器端(文
件名重复的,可以覆盖)。
如果传输过程中服务器端发现客户端断开,服务器端应删除文件,并在屏幕
上提示,如“IP:1.2.3.4 发来abcd.txt 文件过程中失去连接。”。如果客户端发
现服务器端不工作,客户端应有提示“服务器1.2.3.5:62345 失去连接”。

一、UDP传输流程图


二、代码实现

1.1.FileHelper用来进行与文件相关的操作

#include<stdio.h>#include<stdlib.h>#include <WINSOCK2.H>#include <STDIO.H>#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));}};

2.Client端
#pragma comment(lib,"Ws2_32.lib")#include<WinSock2.h>#include<WS2tcpip.h>#include<stdio.h>#include<Windows.h>#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<WinSock2.h>#include<WS2tcpip.h>#include<stdio.h>#include<Windows.h>#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;}


0 0
原创粉丝点击