本文主要向大家介绍了C++语言利用socket的客户端和服务器之间传输文件,通过具体的内容向大家展示,希望对大家学习C++语言有所帮助。
//服务器的代码文件有
/*
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<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<
本文由职坐标整理并发布,了解更多内容,请关注职坐标编程语言C/C+频道!