您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > linux/Unix相关 > 使用TCP协议实现文件传输
使用TCP协议实现文件传输2013-01-1810:35:43我来说两句作者:hanchaoqi收藏我要投稿使用TCP协议实现文件传输。程序会分为服务器端和客户端,首先运行服务器端,监听来自客户端的连接,客户端运行后会通过程序内的服务器端IP地址,向服务器发送连接请求。双方建立请求之后,客户端将所需文件的文件名和绝对路径传输给服务器,如果服务器找到此文件,则将此文件传输给客户端,然后断开连接。具体算法描述如下:【1】服务器端:1、初始化socket服务2、监听连接请求并做相应的处理2.1创建监听套接字2.2监听套接口2.3接受套接字的连接2.4接收客户端传来的数据case文件绝对路径:按照路径找到文件,并打开。提取本地文件名,发回给客户端发送文件总长度给客户端case已准备接收文件完毕if发送缓冲区为空读取文件,写入缓冲区将文件流分成大小相同的组(最后一组可能会小一点),顺次发送给客户端将缓冲区清空case文件成功传送打印消息,退出case文件已存在打印消息,退出2.5关闭同客户端的连接3、释放socket服务【2】客户端:1、初始化socket,winsock服务2、连接服务器,进行数据的传输2.1初始化,创建套接字2.2通过IP地址,向服务器发送连接请求,建立连接2.3主动发送所求文件绝对路径2.4接受服务器端数据并做相应处理case打开文件错误:重新发送文件绝对路径至服务器,请求重发case文件长度:打印消息case文件名:if文件已经存在发送“文件已经存在”else分配缓冲区,并向服务器发送“Ready”消息case文件流:为已接收文件名创建文件打开文件,将文件流数据写入文件,直至接收所有分组数据发送“成功接收“消息3、关闭套接字释放服务源程序:【1】服务器端:头文件:[cpp]/*server.h*/#pragmacomment(lib,WS2_32)#includeWinSock2.h#includeiostream#includeassert.h#includeWindows.h#ifndefCOMMONDEF_H#defineCOMMONDEF_H#defineMAX_PACKET_SIZE10240//数据包的最大长度,单位是sizeof(char)#defineMAXFILEDIRLENGTH256//存放文件路径的最大长度#definePORT4096//端口号//#defineSERVER_IP127.0.0.1//server端的IP地址//各种消息的宏定义#defineINVALID_MSG-1//无效的消息标识#defineMSG_FILENAME1//文件的名称#defineMSG_FILELENGTH2//传送文件的长度#defineMSG_CLIENT_READY3//客户端准备接收文件#defineMSG_FILE4//传送文件#defineMSG_SENDFILESUCCESS5//传送文件成功#defineMSG_OPENFILE_ERROR10//打开文件失败,可能是文件路径错误找不到文件等原因#defineMSG_FILEALREADYEXIT_ERROR11//要保存的文件已经存在了classCCSDef{public:#pragmapack(1)//使结构体的数据按照1字节来对齐,省空间//消息头structTMSG_HEADER{charcMsgID;//消息标识TMSG_HEADER(charMsgID=INVALID_MSG):cMsgID(MsgID){}};//请求传送的文件名//客户端传给服务器端的是全路径名称//服务器传回给客户端的是文件名structTMSG_FILENAME:publicTMSG_HEADER{charszFileName[256];//保存文件名的字符数组TMSG_FILENAME():TMSG_HEADER(MSG_FILENAME){}};//传送文件长度structTMSG_FILELENGTH:publicTMSG_HEADER{longlLength;TMSG_FILELENGTH(longlength):TMSG_HEADER(MSG_FILELENGTH),lLength(length){}};//Client端已经准备好了,要求Server端开始传送文件structTMSG_CLIENT_READY:publicTMSG_HEADER{TMSG_CLIENT_READY():TMSG_HEADER(MSG_CLIENT_READY){}};//传送文件structTMSG_FILE:publicTMSG_HEADER{union//采用union保证了数据包的大小不大于MAX_PACKET_SIZE*sizeof(char){charszBuff[MAX_PACKET_SIZE];struct{intnStart;intnSize;charszBuff[MAX_PACKET_SIZE-2*sizeof(int)];}tFile;};TMSG_FILE():TMSG_HEADER(MSG_FILE){}};//传送文件成功structTMSG_SENDFILESUCCESS:publicTMSG_HEADER{TMSG_SENDFILESUCCESS():TMSG_HEADER(MSG_SENDFILESUCCESS){}};//传送出错信息,包括://MSG_OPENFILE_ERROR:打开文件失败//MSG_FILEALREADYEXIT_ERROR:要保存的文件已经存在了structTMSG_ERROR_MSG:publicTMSG_HEADER{TMSG_ERROR_MSG(charcErrorMsg):TMSG_HEADER(cErrorMsg){}};#pragmapack()};#endifcpp文件:[cpp]/*Server.cpp*/#includeServer.hcharg_szNewFileName[MAXFILEDIRLENGTH];charg_szBuff[MAX_PACKET_SIZE+1];longg_lLength;char*g_pBuff=NULL;//初始化socket库boolInitSocket();//关闭socket库boolCloseSocket();//解析消息并进行相应的处理boolProcessMsg(SOCKETsClient);//监听Client消息voidListenToClient();//打开文件boolOpenFile(CCSDef::TMSG_HEADER*pMagHeader,SOCKETsClient);//传送文件boolSendFile(SOCKETsClient);//读取文件进缓冲区boolReadFile(SOCKETsClient);intmain(){while(1){InitSocket();ListenToClient();CloseSocket();system(delE:\\test1.A_exp);}//system(pause);return0;}//初始化socket库boolInitSocket(){WSADATAwsaData;WORDsocketVersion=MAKEWORD(2,2);if(::WSAStartup(socketVersion,&wsaData)!=0){//初始化WinSock服务printf(Initsocketdllerror\n);returnfalse;}returntrue;}//关闭socket库boolCloseSocket(){//释放winsock库::WSACleanup();if(g_pBuff!=NULL){delete[]g_pBuff;g_pBuff=NULL;}returntrue;}//解析消息并进行相应的处理boolProcessMsg(SOCKETsClient){//从套接口中接收数据,返回copy的字节数intnRecv=::recv(sClient,g_szBuff,MAX_PACKET_SIZE+1,0);if(nRecv0){g_szBuff[nRecv]='\0';}//解析命令CCSDef::TMSG_HEADER*pMsgHeader=(CCSDef::TMSG_HEADER*)g_szBuff;switch(pMsgHeader-cMsgID){caseMSG_FILENAME://文件名{OpenFile(pMsgHeader,sClient);}break;caseMSG_CLIENT_READY://客户端已准备完毕,开始传送文件{SendFile(sClient);}break;caseMSG_SENDFILESUCCESS://传送文件成功{printf(SendFileSuccess!\n);returnfalse;}break;caseMSG_FILEALREADYEXIT_ERROR://要保存的文件已经存在{printf(Thefilereadytosendalreadyexit!\n);returnfalse;}break;}returntrue;}//监听Client消息voidListenToClient(){//创建套接字SOCKETsListen=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(sListen==SOCKET_ERROR){printf(InitSocketError!\n);return;}//绑定socketsockaddr_insin;sin.sin_family=AF_INET;sin.sin_port=htons(PORT);sin.sin_addr.S_un.S_addr=INADDR_ANY;if(::bind(sListen,(LPSOCKADDR)&sin,sizeof(sockaddr_in))==SOCKET_ERROR){printf(BindError!\n);return;}//设置socket进入监听状态if(::listen(sListen,10)==SOCKET_ERROR){printf(ListenError!\n);return;}printf(ListeningToClient...\n);//循环接收client端的连接请求sockaddr_inClientAddr;intnAddrLen=sizeof(sockaddr_in);SOCKETsClient;//取队列最前端客户连接请求,创建套接字连接通道while((sClient=::accept(sListen,(sockaddr*)&ClientAddr,&nAddrLen))==INVALID_SOCKET){}//解析消息并进行相应的处理//intcount=10;//作为定时当程序执行10s未完成时直接退出//while(ProcessMsg(sClient)==true&&count0)//{//Sleep(1000);//count--;//}while(ProcessMsg(sClient)==true){Sleep(1000);}//关闭同客户端的连接::closesocket(sClient);::closesocket(sListen);}//打开文件boolOpenFile(CCSDef::TMSG_HEADER*pMsgHeader,SOCKETsClient){CCSDef::TMSG_FILENAME*pRequstFileNameMsg=(CCSDef::TMSG_FILENAME*)pMsgHeader;//对文件名进行处理char*p1,*p2;for(p1=pRequstFileNameMsg-szFileName,p2=g_szNewFileName;*p1!='\0';p1++,p2
本文标题:使用TCP协议实现文件传输
链接地址:https://www.777doc.com/doc-5492287 .html