1. 程式人生 > >C++利用socket的客戶端和伺服器之間傳輸檔案

C++利用socket的客戶端和伺服器之間傳輸檔案

//伺服器的程式碼檔案有
/*
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;
	}
	server.sd=server.BindListen();
	if(server.sd==INVALID_SOCKET)
	{
		return -1;
	}
	SOCKET sdListen=server.AcceptConnection(server.sd);
	if(sdListen==INVALID_SOCKET)
	{
		return -1;
	}
	while(server.ProcessConnection(sdListen))
	{
	}
	server.CloseSocket();
	return 0;
}
bool Server::InitSock()   //初始化winsocket
{
	WSADATA wsData;
	WORD wr=MAKEWORD(2,2);
	if(WSAStartup(wr,&wsData)==0)
	{
		return true;
	}
	return false;
}
SOCKET Server::BindListen()  //繫結套接字
{
	SOCKET sd=socket(AF_INET,SOCK_STREAM,0);
	if(sd==INVALID_SOCKET)
	{
		cout<<"建立套接字失敗"<<WSAGetLastError()<<endl;
		return INVALID_SOCKET;
	}
	sockaddr_in sListen;
	sListen.sin_family=AF_INET;
	sListen.sin_addr.s_addr=htonl(INADDR_ANY);
	sListen.sin_port=htons(PORT);
	int nSize;
	nSize=sizeof(sockaddr_in);
	if(bind(sd,(sockaddr*)&sListen,nSize)==SOCKET_ERROR)
	{
		closesocket(sd);
		cout<<"繫結失敗"<<WSAGetLastError()<<endl;
		return INVALID_SOCKET;
	}
	if(listen(sd,10)==SOCKET_ERROR)
	{
		closesocket(sd);
		cout<<"監聽失敗"<<WSAGetLastError()<<endl;
		return INVALID_SOCKET;
	}
	return sd;
	
}
SOCKET Server::AcceptConnection(SOCKET sd)    //接收客戶端
{
	sockaddr_in saRemote;
	int nSize=sizeof(sockaddr_in);
	SOCKET sdListen=accept(sd,(sockaddr*)&saRemote,&nSize);
	if(sdListen==INVALID_SOCKET)
	{
		cout<<"接收客戶端失敗"<<WSAGetLastError()<<endl;
		return INVALID_SOCKET;
	}
	return sdListen;
}
bool Server::ReceiveFile(SOCKET sd)
{
    char buff[MAX_PACK_SIZE];
    FILE *pFile;
	pFile=fopen(fileName,"a+b");
	_int64 i=0;
    while(i+1<fileLength)
	{
		int nRecv=recv(sd,buff,MAX_PACK_SIZE,0);
        if(nRecv==SOCKET_ERROR)
		{
		   return false;
		}
		fwrite(buff,sizeof(char),nRecv,pFile);
		i+=nRecv;
	    memset(buff,0,sizeof(char)*MAX_PACK_SIZE);
	}
	fclose(pFile);
	return true;
}
void Server::CloseSocket()
{
	closesocket(sd);
	WSACleanup();
}
bool Server::ProcessConnection(SOCKET sd)
{
	//----------------------------------------------
	//可以將下面程式碼看做設定系統緩衝區
	int nRecvBuf=1024000;//設定為1000K
    setsockopt(sd,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
      //傳送緩衝區
    int nSendBuf=1024000;//設定為1000K
    setsockopt(sd,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
	//-------------------------------------------------------------
	char buff[MAX_PACK_SIZE];
	Message::MsgHead *msgHead;
	if(recv(sd,buff,MAX_PACK_SIZE,0)==SOCKET_ERROR)
	{
		cout<<"接收失敗"<<WSAGetLastError()<<endl;
		return false;
	}
	msgHead=(Message::MsgHead *)&buff;
	switch(msgHead->msgId)
	{
	case MSG_SEND_FILE:         //客戶端向伺服器傳送檔案
		cout<<"客戶端請求向伺服器傳送檔案"<<endl;
		break;
	case MSG_DOWNLOAD_FILE:      //客戶端從伺服器下載檔案
		{
			cout<<"客戶端請求從伺服器下載檔案"<<endl;
			Source source;      //用來獲取指定檔案加下的字尾為jpg檔案
			string sPath="E:\\圖片";
			string sExt=".jpg";
			source.GetFiles(sPath,sExt,source.catalogInfo);
			int nSize;
			nSize=source.catalogInfo.size();
			cout<<"蒐集到"<<nSize<<"個檔案"<<endl;
            char buff[MAX_PACK_SIZE];
			for(int i=0;i<nSize;i++)   //將目錄資訊傳送到客戶端
			{
				strcpy(buff,source.catalogInfo[i].c_str());
				//cout<<source.catalogInfo[i]<<endl;
				if(send(sd,buff,MAX_PACK_SIZE,0)==SOCKET_ERROR)
				{
					cout<<"傳送目錄資訊失敗"<<WSAGetLastError()<<endl;
					return false;
				}
				Sleep(10);   //睡眠10ms讓接收端將資訊取走
			}
			Message::MsgComplete msgComplete;
			if(send(sd,(char *)&msgComplete,sizeof(Message::MsgComplete),0)==SOCKET_ERROR)
			{
				cout<<"傳送完成資訊失敗"<<WSAGetLastError()<<endl;
				return false;
			}
			Sleep(10);
			if(!RecvFileName(sd))
			{
				return false;
			}
			Sleep(10);
			if(!GetAndSendFileLength(sd))
			{
				return false;
			}
			Sleep(10);
			if(!SendFileName(sd))
			{
				return false;
			}
			Sleep(10);
			if(!SendFile(sd))
			{
				return false;
			}
		}
		break;
	case MSG_FILE_NAME:      //傳送的檔名
		{
			Message::MsgFileName *msgFileName;
		    msgFileName=(Message::MsgFileName*)msgHead;
		    strcpy(fileName,msgFileName->fileName);
		    cout<<"收到傳送來的檔名"<<fileName<<endl;
		}
		break;
	case MSG_FILE_LENGTH:    //傳送的檔案長度
		{
			Message::MsgFileLength *msgFileLength;
			msgFileLength=(Message::MsgFileLength *)msgHead;
			fileLength=msgFileLength->fileLength;
			cout<<"接收到檔案的長度為"<<fileLength<<endl;
		}
		break;
	case MSG_FILE:     //傳送的檔案內容
		{
			cout<<"開始接收檔案"<<endl;
			if(!ReceiveFile(sd))
			{
				cout<<"接收檔案失敗"<<endl;
				return false;
			}
		}
		break;
	default:
		cout<<"非標準訊息"<<endl;
		return false;
	}
	return true;
}
bool Server::RecvFileName(SOCKET sd)
{
	//memset(fileName,0,sizeof(char)*MAX_FILE_NAME_LENGTH);  //清空
	char buff[MAX_PACK_SIZE];
	Message::MsgFileName *msgFileName;
	if(recv(sd,buff,MAX_PACK_SIZE,0)==SOCKET_ERROR)
	{
		cout<<"接收檔名失敗"<<WSAGetLastError()<<endl;
		return false;
	}
	msgFileName=(Message::MsgFileName *)buff;
	strcpy(fileName,msgFileName->fileName);
	cout<<"接收的檔名為"<<fileName<<endl;
	return true;
}
bool Server::GetAndSendFileLength(SOCKET sd)       //獲取客戶端要下載的檔案長度
{
	Message::MsgFileLength msgFileLength;
	FILE *pFile;
	pFile=fopen(fileName,"r+b");
	if(pFile==NULL)
	{
		cout<<"開啟檔案失敗"<<endl;
		return false;
	}
	fseek(pFile,0,SEEK_END);
    fileLength=_ftelli64(pFile);
	fclose(pFile);
	msgFileLength.fileLength=fileLength;
	if(send(sd,(char*)&msgFileLength,sizeof(Message::MsgFileLength),0)==SOCKET_ERROR)
	{
		cout<<"傳送檔案長度失敗"<<WSAGetLastError()<<endl;
		return false;
	}
	return true;
}
bool Server::SendFileName(SOCKET sd)       //向客戶端傳送檔名
{
	Message::MsgFileName msgFileName;
	char fileDrive[_MAX_DRIVE];
	char fileDir[_MAX_DIR];
	char Name[_MAX_FNAME];
	char fileExt[_MAX_EXT];
	_splitpath(fileName,fileDrive,fileDir,Name,fileExt);
	strcat(Name,fileExt);
	strcpy(msgFileName.fileName,Name);
	cout<<"要傳送的檔名為"<<Name<<endl;
	if(send(sd,(char *)&msgFileName,sizeof(Message::MsgFileName),0)==SOCKET_ERROR)
	{
		cout<<"傳送檔名出錯"<<WSAGetLastError()<<endl;
		return false;
	}
	return true;
}
bool Server::SendFile(SOCKET sd)  //向客戶端傳送檔案
{
	cout<<"進入到傳送檔案內容"<<endl;
	cout<<"要傳送的檔案為"<<fileName<<endl;
	FILE *pFile;
	pFile=fopen(fileName,"r+b");
	fseek(pFile,0,SEEK_SET);   //定位到檔案首位置
	_int64 i=0;
	char buff[MAX_PACK_SIZE];
	cout<<"要傳送的檔案長度為"<<fileLength<<endl;
	while(i<fileLength)
	{
		int nSize;
		if(i+MAX_PACK_SIZE>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;
			return false;
		}
		i+=nSend;
		fseek(pFile,-(nSize-nSend),SEEK_CUR);  //定位到實際已傳送到的位置
		memset(buff,0,sizeof(char)*MAX_PACK_SIZE); //將buff清空
	}
	fclose(pFile);
	return true;
}
//client.h
#pragma once
#include<iostream>
#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;
		return -1;
	}
	SOCKET saRemote=client.ConnectServer(client.ResolveAdress(SERVER_IP),PORT);
	if(saRemote==INVALID_SOCKET)
	{
		cout<<"連線伺服器失敗"<<endl;
		return -1;
	}
	if(!client.ProcessConnection(saRemote))
	{
		return -1;
	}
	client.CloseSocket();
	return 0;
}
bool Client::InitSock()    //初始socket
{
	WSADATA wsData;
	WORD wr=MAKEWORD(2,2);
	if(WSAStartup(wr,&wsData)==0)
	{
		return true;
	}
	return false;
}
u_long Client::ResolveAdress(char *serverIp)   //解析IP地址
{
	u_long nAddr=inet_addr(serverIp);
	if(nAddr==INADDR_NONE)  //表明serverIp使用的是主機名形式
	{
		hostent *ent=gethostbyname(serverIp);
		if(ent==NULL)
		{
			cout<<"獲取主機名出錯"<<WSAGetLastError()<<endl;
		}
		else
		{
			nAddr=*((u_long *)ent->h_addr_list[0]);
		}
	}
	if(nAddr==INADDR_NONE)
	{
		cout<<"解析主機地址失敗"<<endl;
	}
	return nAddr;
}
SOCKET Client::ConnectServer(u_long serverIp,int port)   //連線伺服器
{
	sd=socket(AF_INET,SOCK_STREAM,0);
	if(sd==INVALID_SOCKET)
	{
		cout<<"床架套接字失敗"<<endl;
		return INVALID_SOCKET;
	}
	sockaddr_in saServer;
	saServer.sin_family=AF_INET;
	saServer.sin_addr.S_un.S_addr=serverIp;
	saServer.sin_port=htons(port);
	if(connect(sd,(sockaddr*)&saServer,sizeof(sockaddr_in))==SOCKET_ERROR)
	{
		cout<<"連線伺服器失敗"<<WSAGetLastError()<<endl;
		closesocket(sd);
		return INVALID_SOCKET;
	}
	return sd;
}
bool Client::ProcessConnection(SOCKET sd)      //進行通訊
{
	//-------------------------------------------------
	//可以將下面程式碼看做設定系統緩衝區
	int nRecvBuf=1024000;//設定為1000K
    setsockopt(sd,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
      //傳送緩衝區
    int nSendBuf=1024000;//設定為1000K
    setsockopt(sd,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
	//---------------------------------------------------------
	while(true)
	{
		cout<<"(1)向伺服器傳送檔案"<<endl;
		cout<<"(2)從伺服器下載檔案"<<endl;
		cout<<"(3)退出業務"<<endl;
		int n;
		loop:cin>>n;
		switch(n)
		{
		case 1:
			{
				//向伺服器傳送傳送檔案訊息
				Message::MsgSendFile msgSendFile;
				if(send(sd,(char *)&msgSendFile,sizeof(Message::MsgSendFile),0)==SOCKET_ERROR)
				{
					cout<<"傳送訊息失敗"<<endl;
					return false;
				}
				Sleep(10);     //睡眠10ms保證對方將傳送的訊息取走
				char filePath[MAX_FILE_NAME_LENGTH];
				cout<<"請輸入檔案路徑如:F:/a/b.jpg"<<endl;
				cin>>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;
				}
				Sleep(10);
                if(!SendFileLength(sd,filePath))  //傳送檔案長度
				{
					cout<<"傳送檔案長度出錯"<<endl;
					return false;
				}
				Sleep(10);
				if(!SendFile(sd,filePath))  //傳送檔案
				{
					cout<<"傳送檔案出錯"<<endl;
					return false;
				}
			}
			break;
		case 2:
			{
				Message::MsgDownLoadFile msgDownLoadFile;
				if(send(sd,(char *)&msgDownLoadFile,sizeof(Message::MsgDownLoadFile),0)==SOCKET_ERROR)
				{
					cout<<"傳送下載檔案訊息失敗"<<WSAGetLastError()<<endl;
					return false;
				}
				if(!RecvCatalogInfo(sd))
				{
					return false;
				}
				if(!SendDownLoadFileName(sd))
				{
					return false;
				}
				if(!ReceiveFileLength(sd))
				{
					return false;
				}
				if(!ReceiveFileName(sd))
				{
					return false;
				}
				if(!ReceiveFile(sd))
				{
					return false;
				}
			}
			break;
		case 3:
			break;
		default:
			cout<<"你輸入的不符合要求,重新輸入"<<endl;
			goto loop;
		}
	}
	return true;
}
bool Client::SendFileLength(SOCKET sd,char *filePath)
{
	
	FILE *pFile;
	pFile=fopen(filePath,"r+b");
	fseek(pFile,0,SEEK_END);
	nFileLength=_ftelli64(pFile);
	Message::MsgFileLength msgFileLength;
	msgFileLength.fileLength=nFileLength;
	fclose(pFile);
	if(send(sd,(char *)&msgFileLength,sizeof(Message::MsgFileLength),0)==SOCKET_ERROR)
	{
		return false;
	}
	return true;
}
bool Client::SendFile(SOCKET sd,char *filePath)   //傳送檔案
{
	cout<<"進入到傳送檔案內容"<<endl;
	Message::MsgFile msgFile;
	if(send(sd,(char *)&msgFile,sizeof(Message::MsgFile),0)==SOCKET_ERROR)
	{
	    cout<<"傳送檔案訊息出錯"<<WSAGetLastError()<<endl;
		return false;
	}
	Sleep(10);
	FILE *pFile;
	pFile=fopen(filePath,"r+b");
	fseek(pFile,0,SEEK_SET);   //定位到檔案首位置
	_int64 i=0;
	char buff[MAX_PACK_SIZE];
	while(i<nFileLength)
	{
		int nSize;
		if(i+MAX_PACK_SIZE>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;
			return false;
		}
		i+=nSend;
		fseek(pFile,-(nSize-nSend),SEEK_CUR);  //定位到實際已傳送到的位置
		memset(buff,0,sizeof(char)*MAX_PACK_SIZE); //將buff清空
	}
	fclose(pFile);
	return true;
}
bool Client::RecvCatalogInfo(SOCKET sd)   //接收目錄資訊
{
	int flag=1;     //接收目錄資訊成功標誌
	char buff[MAX_PACK_SIZE];
	Message::MsgHead *msgHead;
    while(true)
	{
		if(recv(sd,buff,MAX_PACK_SIZE,0)==SOCKET_ERROR)
		{
			cout<<"接收目錄資訊失敗"<<WSAGetLastError()<<endl;
			flag=0;
			break;
		}
		msgHead=(Message::MsgHead *)buff;
		if(msgHead->msgId==MSG_COMPLETE)      //判斷訊息是否是標準訊息
		{
			cout<<"目錄資訊傳送完成"<<endl;
			break;
		}
		else
		{
			cout<<buff<<endl;     //傳送來的是目錄資訊,即檔名
		}
	}
	if(flag==0)
	{
		return false;
	}
	return true;
}
bool Client::SendDownLoadFileName(SOCKET sd)      //傳送下載的檔名
{
	cout<<"請輸入你要下載的檔名"<<endl;
	char fileName[_MAX_FNAME+_MAX_EXT];
	cin>>fileName;
	Message::MsgFileName msgFileName;
	strcpy(msgFileName.fileName,fileName);
	if(send(sd,(char *)&msgFileName,MAX_PACK_SIZE,0)==SOCKET_ERROR)
	{
		cout<<"傳送下載檔名出錯"<<WSAGetLastError()<<endl;
		return false;
	}
	return true;
}
bool Client::ReceiveFileLength(SOCKET sd)     //接收下載的檔案長度
{
	char buff[MAX_PACK_SIZE];
	Message::MsgFileLength *msgFileLength;
	if(recv(sd,buff,MAX_PACK_SIZE,0)==SOCKET_ERROR)
	{
		cout<<"接收檔案長度失敗"<<WSAGetLastError()<<endl;
		return false;
	}
	msgFileLength=(Message::MsgFileLength *)buff;
	nFileLength=msgFileLength->fileLength;
	cout<<"接收到檔案長度"<<nFileLength<<endl;
	return true;
}
bool Client::ReceiveFileName(SOCKET sd)   //接收下載的檔名
{
	char buff[MAX_PACK_SIZE];
	memset(fileName,0,sizeof(char)*(_MAX_FNAME+_MAX_EXT));
	Message::MsgFileName *msgFileName;
	if(recv(sd,buff,MAX_PACK_SIZE,0)==SOCKET_ERROR)
	{
		cout<<"接收檔名出錯"<<endl;
		return false;
	}
	msgFileName=(Message::MsgFileName *)buff;
	strcpy(fileName,msgFileName->fileName);
	cout<<"接收到檔名"<<fileName<<endl;
	return true;
}
bool Client::ReceiveFile(SOCKET sd)      //接收檔案內容
{
   char buff[MAX_PACK_SIZE];
   FILE *pFile;
   pFile=fopen(fileName,"a+b");
   _int64 i=0;
   while(i+1<nFileLength)
   {
		int nRecv=recv(sd,buff,MAX_PACK_SIZE,0);
        if(nRecv==SOCKET_ERROR)
		{
		    return false;
		}
		fwrite(buff,sizeof(char),nRecv,pFile);
		i+=nRecv;
	    memset(buff,0,sizeof(char)*MAX_PACK_SIZE);
	}
	fclose(pFile);
	return true;
}
void Client::CloseSocket()   //關閉套接字
{
	closesocket(sd);
	WSACleanup();
}