C++利用socket的客户端和服务器之间传输文件
程序员文章站
2022-04-12 21:14:18
//服务器的代码文件有
/*
message.h
source.h
source.cpp
server.h
server.cpp
*/
//...
//服务器的代码文件有 /* message.h source.h source.cpp server.h server.cpp */ //客户端的代码文件有 /* message.h 和服务器端一样 client.h client.cpp */ //message.h #pragma once #include using namespace std; #define MAX_PACK_SIZE 10240 //数据包的长度 #define MAX_FILE_NAME_LENGTH 256 //文件名的长度 #define INVALID_MSG -1 //无效的消息 #define MSG_FILE_LENGTH 1 //文件长度 #define MSG_FILE_NAME 2 //文件名 #define MSG_FILE 4 //文件内容 #define MSG_READY 3 //准备好消息 #define MSG_SEND_FILE 5 //发送文件 #define MSG_DOWNLOAD_FILE 6 //下载文件 #define MSG_COMPLETE 7 //完成信息 class Message { public: struct MsgHead //头消息 { int msgId; //消息标识 MsgHead(int msg=INVALID_MSG):msgId(msg){}; }; struct MsgFileLength :public MsgHead { _int64 fileLength; //文件长度 MsgFileLength():MsgHead(MSG_FILE_LENGTH){} }; struct MsgFileName:public MsgHead { char fileName[MAX_FILE_NAME_LENGTH]; MsgFileName():MsgHead(MSG_FILE_NAME){} }; struct MsgFile:public MsgHead { MsgFile():MsgHead(MSG_FILE){} }; struct MsgReady:public MsgHead //准备好消息 { MsgReady():MsgHead(MSG_READY){} }; struct MsgSendFile:public MsgHead //发送文件消息 { MsgSendFile():MsgHead(MSG_SEND_FILE){} }; struct MsgDownLoadFile:public MsgHead //下载文件消息 { MsgDownLoadFile():MsgHead(MSG_DOWNLOAD_FILE){} }; struct MsgComplete:public MsgHead { MsgComplete():MsgHead(MSG_COMPLETE){} }; }; //source.h 获取指定文件加下的符合要求的文件 #pragma once #include #include #include #include #include using namespace std; class Source { public: vector catalogInfo; void GetFiles(string path,string ext,vector &files);//获取文件 }; //server.h #pragma once #include #include #include"message.h" #pragma comment(lib,"Ws2_32.lib") #define PORT 10000 using namespace std; class Server { public: SOCKET sd; _int64 fileLength; char fileName[MAX_FILE_NAME_LENGTH]; bool InitSock(); //初始winsocket SOCKET BindListen(); //绑定监听套接字 SOCKET AcceptConnection(SOCKET sd); //接收客户端 bool ProcessConnection(SOCKET sd); //传送数据 bool ReceiveFile(SOCKET sd); //接收文件内容 bool RecvFileName(SOCKET sd); //接收文件名 bool GetAndSendFileLength(SOCKET sd); //获取文件长度 bool SendFileName(SOCKET sd); //发送文件名 bool SendFile(SOCKET sd); //发送文件 void CloseSocket(); //关闭套接字 }; //source.cpp #pragma once #include #include #include #include #include"source.h" using namespace std; void Source::GetFiles(string path,string ext,vector &files) { long hFile=0; //文件句柄 _finddata_t fileInfo; //文件信息 string pathName; if((hFile=_findfirst(pathName.assign(path).append("\\*").c_str(),&fileInfo))!=-1) //判断路径是否有效并获取第一个文件 { do { if(fileInfo.attrib & _A_SUBDIR) //如果是子文件夹 { if(strcmp(fileInfo.name,".")!=0 && strcmp(fileInfo.name,"..")!=0) { GetFiles(pathName.assign(path).append("\\").append(fileInfo.name),ext,files); } } else { string filePath; filePath=pathName.assign(path).append("\\").append(fileInfo.name); char fileDrive[_MAX_DRIVE]; char fileDir[_MAX_DIR]; char fileName[_MAX_FNAME]; char fileExt[_MAX_EXT]; _splitpath(filePath.c_str(),fileDrive,fileDir,fileName,fileExt); //分解路径获取磁盘区路径文件名后缀 if(strcmp(fileExt,ext.c_str())==0) { files.push_back(filePath); } } }while(_findnext(hFile,&fileInfo)==0); _findclose(hFile); } } //server.cpp #pragma once #include #include #include #include #include"message.h" #include"server.h" #include"source.h" using namespace std; int main() { Server server; if(!server.InitSock()) //初始化失败 { cout<<"初始化失败"<msgId) { case MSG_SEND_FILE: //客户端向服务器发送文件 cout<<"客户端请求向服务器发送文件"<fileName); cout<<"收到发送来的文件名"<fileLength; cout<<"接收到文件的长度为"<fileName); cout<<"接收的文件名为"<fileLength) { nSize=(int)(fileLength-i); } else { nSize=MAX_PACK_SIZE-1; } fread(buff,sizeof(char),nSize,pFile); int nSend; nSend=send(sd,buff,nSize,0); if(nSend==SOCKET_ERROR) { cout<<"发送失败"< #include #include #include #pragma comment(lib,"Ws2_32.lib") using namespace std; #define SERVER_IP "127.0.0.1" #define PORT 10000 class Client { public: _int64 nFileLength; char fileName[_MAX_FNAME+_MAX_EXT]; SOCKET sd; bool InitSock(); //初始化winsock u_long ResolveAdress(char *serverIp); //解析服务器地址 SOCKET ConnectServer(u_long serverIp,int port);//连接服务器 bool ProcessConnection(SOCKET sd); //客户端服务器交互 void CloseSocket(); //释放套接字 bool SendFileLength(SOCKET sd,char *filePath); //发送文件长度 bool SendFile(SOCKET sd,char *filePath); //发送文件 bool RecvCatalogInfo(SOCKET sd); //接收目录信息 bool SendDownLoadFileName(SOCKET sd); //发送要下载的文件名 bool ReceiveFileLength(SOCKET sd); //接收文件长度 bool ReceiveFileName(SOCKET sd); //接收文件名 bool ReceiveFile(SOCKET sd); //接收文件 //void DoWork(); //主体函数 }; //client.cpp #define _CRT_SECURE_NO_WARNINGS #pragma once #include #include #include #include"client.h" #include"message.h" using namespace std; int main() { Client client; if(!client.InitSock()) { cout<<"初始socket失败"<h_addr_list[0]); } } if(nAddr==INADDR_NONE) { cout<<"解析主机地址失败"<>n; switch(n) { case 1: { //向服务器发送传送文件消息 Message::MsgSendFile msgSendFile; if(send(sd,(char *)&msgSendFile,sizeof(Message::MsgSendFile),0)==SOCKET_ERROR) { cout<<"发送消息失败"<>filePath; char fileDrive[_MAX_DRIVE]; char fileDir[_MAX_DIR]; char fileName[_MAX_FNAME]; char fileExt[_MAX_EXT]; _splitpath(filePath,fileDrive,fileDir,fileName,fileExt); //将文件路径解析 Message::MsgFileName msgFileName; strcat(fileName,fileExt); strcpy(msgFileName.fileName,fileName); if(send(sd,(char *)&msgFileName,sizeof(Message::MsgFileName),0)==SOCKET_ERROR) //发送文件名 { cout<<"发送文件名出错"<nFileLength) { nSize=(int)(nFileLength-i); } else { nSize=MAX_PACK_SIZE-1; } fread(buff,sizeof(char),nSize,pFile); int nSend; nSend=send(sd,buff,nSize,0); if(nSend==SOCKET_ERROR) { cout<<"发送失败"<msgId==MSG_COMPLETE) //判断消息是否是标准消息 { cout<<"目录信息发送完成"<>fileName; Message::MsgFileName msgFileName; strcpy(msgFileName.fileName,fileName); if(send(sd,(char *)&msgFileName,MAX_PACK_SIZE,0)==SOCKET_ERROR) { cout<<"发送下载文件名出错"<fileLength; cout<<"接收到文件长度"<fileName); cout<<"接收到文件名"<
上一篇: jsp页面之间传值
下一篇: JSP自定义标签实现数据字典
推荐阅读
-
Python实现的简单文件传输服务器和客户端
-
Windows本地环境和Linux腾讯云服务器之间传输文件的方法
-
Python实现的简单文件传输服务器和客户端
-
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
-
C++利用socket的客户端和服务器之间传输文件
-
网络编程(InetAddress类、Socket和ServerSocket、实现客户端和服务器之间的双向通信)
-
Windows本地环境和Linux腾讯云服务器之间传输文件的方法
-
C++利用socket的客户端和服务器之间传输文件
-
Python实现的简单文件传输服务器和客户端
-
Python实现的简单文件传输服务器和客户端