摘要:本文主要向大家介绍了C++语言利用socket的客户端和服务器之间传输文件,通过具体的内容向大家展示,希望对大家学习C++语言有所帮助。
本文主要向大家介绍了C++语言利用socket的客户端和服务器之间传输文件,通过具体的内容向大家展示,希望对大家学习C++语言有所帮助。
//服务器的代码文件有
/*
message.h
source.h
source.cpp
server.h
server.cpp
*/
//客户端的代码文件有
/*
message.h 和服务器端一样
client.h
client.cpp
*/
//message.h
#pragma once
#include<iostream>
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<iostream>
#include<fstream>
#include<vector>
#include<io.h>
#include<string>
using namespace std;
class Source
{
public:
vector<string> catalogInfo;
void GetFiles(string path,string ext,vector<string> &files);//获取文件
};
//server.h
#pragma once
#include<iostream>
#include<winsock2.h>
#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<iostream>
#include<vector>
#include<io.h>
#include<string>
#include"source.h"
using namespace std;
void Source::GetFiles(string path,string ext,vector<string> &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<iostream>
#include<string>
#include<fstream>
#include<winsock2.h>
#include"message.h"
#include"server.h"
#include"source.h"
using namespace std;
int main()
{
Server server;
if(!server.InitSock()) //初始化失败
{
cout<<"初始化失败"<<endl; ----------------------------------------------="" -------------------------------------------------------------="" _int64="" bool="" char="" const="" file="" i="0;" int="" message::msghead="" msghead="(Message::MsgHead" msghead-="" nrecv="=SOCKET_ERROR)" nrecvbuf="1024000;//设置为1000K" nsendbuf="1024000;//设置为1000K" nsize="sizeof(sockaddr_in);" pfile="fopen(fileName,"a+b");" return="" sd="=INVALID_SOCKET)" sdlisten="=INVALID_SOCKET)" server.sd="=INVALID_SOCKET)" slisten.sin_addr.s_addr="htonl(INADDR_ANY);" slisten.sin_family="AF_INET;" slisten.sin_port="htons(PORT);" sockaddr_in="" socket="" void="" winsocket="" word="" wr="MAKEWORD(2,2);" wsadata="">msgId)
{
case MSG_SEND_FILE: //客户端向服务器发送文件
cout<<"客户端请求向服务器发送文件"<<endl; case="" char="" i="0;i<nSize;i++)" int="" message::msgcomplete="" message::msgfilename="" msg_download_file:="" msg_file_name:="" msgfilename="(Message::MsgFileName*)msgHead;" msgfilename-="" nsize="source.catalogInfo.size();" return="" sext=".jpg" source="" spath="E:\\图片" string="">fileName);
cout<<"收到发送来的文件名"<<filename<<endl; case="" filelength="msgFileLength-" message::msgfilelength="" msg_file_length:="" msgfilelength="(Message::MsgFileLength">fileLength;
cout<<"接收到文件的长度为"<<filelength<<endl; bool="" case="" char="" default:="" message::msgfilename="" msg_file:="" msgfilename="(Message::MsgFileName" msgfilename-="" return="" socket="">fileName);
cout<<"接收的文件名为"<<filename<<endl; _int64="" bool="" char="" file="" filelength="_ftelli64(pFile);" i="0;" int="" max_pack_size="" message::msgfilelength="" message::msgfilename="" msgfilelength.filelength="fileLength;" pfile="=NULL)" return="" socket="">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<<"发送失败"<<wsagetlasterror()<<endl; client.h="" iostream="" once="" pragma="" return="">
#include<fstream>
#include<vector>
#include<winsock2.h>
#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<iostream>
#include<vector>
#include<winsock2.h>
#include"client.h"
#include"message.h"
using namespace std;
int main()
{
Client client;
if(!client.InitSock())
{
cout<<"初始socket失败"<<endl; bool="" char="" else="" ent="=NULL)" ent-="" hostent="" naddr="=INADDR_NONE)" return="" saremote="=INVALID_SOCKET)" socket="" u_long="" word="" wr="MAKEWORD(2,2);" wsadata="">h_addr_list[0]);
}
}
if(nAddr==INADDR_NONE)
{
cout<<"解析主机地址失败"<<endl; -------------------------------------------------="" ---------------------------------------------------------="" bool="" const="" int="" loop:cin="" nrecvbuf="1024000;//设置为1000K" nsendbuf="1024000;//设置为1000K" return="" saserver.sin_addr.s_un.s_addr="serverIp;" saserver.sin_family="AF_INET;" saserver.sin_port="htons(port);" sd="=INVALID_SOCKET)" sockaddr_in="" socket="" u_long="">>n;
switch(n)
{
case 1:
{
//向服务器发送传送文件消息
Message::MsgSendFile msgSendFile;
if(send(sd,(char *)&msgSendFile,sizeof(Message::MsgSendFile),0)==SOCKET_ERROR)
{
cout<<"发送消息失败"<<endl; a="" char="" cin="" f:="" return="">>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<<"发送文件名出错"<<wsagetlasterror()<<endl; 2:="" 3:="" _int64="" bool="" case="" char="" default:="" file="" goto="" i="0;" int="" max_pack_size="" message::msgdownloadfile="" message::msgfile="" message::msgfilelength="" msgfilelength.filelength="nFileLength;" nfilelength="_ftelli64(pFile);" pfile="fopen(filePath,"r+b");" return="" socket="">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<<"发送失败"<<endl; bool="" char="" flag="1;" int="" message::msghead="" msghead="(Message::MsgHead" msghead-="" return="" socket="">msgId==MSG_COMPLETE) //判断消息是否是标准消息
{
cout<<"目录信息发送完成"<<endl; bool="" char="" cin="" else="" flag="=0)" return="" socket="">>fileName;
Message::MsgFileName msgFileName;
strcpy(msgFileName.fileName,fileName);
if(send(sd,(char *)&msgFileName,MAX_PACK_SIZE,0)==SOCKET_ERROR)
{
cout<<"发送下载文件名出错"<<wsagetlasterror()<<endl; bool="" char="" message::msgfilelength="" msgfilelength="(Message::MsgFileLength" nfilelength="msgFileLength-" return="" socket="">fileLength;
cout<<"接收到文件长度"<<nfilelength<<endl; bool="" char="" message::msgfilename="" msgfilename="(Message::MsgFileName" msgfilename-="" return="" socket="">fileName);
cout<<"接收到文件名"<<filename<<endl; _int64="" bool="" char="" file="" i="0;" int="" nrecv="=SOCKET_ERROR)" pfile="fopen(fileName,"a+b");" pre="" return="" socket="" void="">
</filename<<endl;></nfilelength<<endl;></wsagetlasterror()<<endl;></endl;></endl;></wsagetlasterror()<<endl;></endl;></endl;></endl;></winsock2.h></vector></iostream></winsock2.h></vector></fstream></wsagetlasterror()<<endl;></filename<<endl;></filelength<<endl;></filename<<endl;></endl;></endl;></winsock2.h></fstream></string></iostream></string></string></io.h></vector></iostream></winsock2.h></iostream></string></string></string></io.h></vector></fstream></iostream></iostream>
本文由职坐标整理并发布,了解更多内容,请关注职坐标编程语言C/C+频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号