//
Server.cpp : 定义控制台应用程序的入口点。
// 需在项目设置 链接中添加ws2_32.lib
#include " stdafx.h "
#include < winsock2.h >
#include < iostream >
#include < fstream >
#include < io.h >
#include < string >
#include < vector >
#include < iomanip >
#include < ctime >
using namespace std;
#define DEFAULT_PORT 2100 // 默认服务器端口
#define DEFAULT_BUFFER 4096 // 默认缓冲区大小
char path[ 1024 ]; // FTP服务器的服务目录
# define DEFAULT_PATH " C: " // 默认目录
bool sendList(LPVOID ,vector < _finddata_t > & ,vector < _finddata_t > & ); // 发送文件列表
bool down(LPVOID,vector < _finddata_t > & ); // 发送文件
DWORD WINAPI ClientThread(LPVOID ); // 服务器线程
void setDirectory(); // 设置FTP服务器的服务目录
void exit(); // 退出动作
int main()
... {
setDirectory();//设置FTP服务器目录
WSADATA wsd; //The WSADATA structure contains information about the Windows Sockets implementation
SOCKET sListen,sClient;//服务器和客户端的套接
int iAddrSize;
HANDLE hThread;
DWORD dwThreadId;
struct sockaddr_in local,client; // address information
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)
...{
cout<<"Faile to load Winsock!"<<' ';
exit(); //退出动作
return 1;
}
sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);//创建监听套接字
if(sListen==SOCKET_ERROR)
...{
cout<<"socket() failed: "<<WSAGetLastError()<<' ';
exit(); //退出动作
return 1;
}
local.sin_addr.s_addr=htonl(INADDR_ANY);
local.sin_family=AF_INET;
local.sin_port=htons(DEFAULT_PORT);
if(bind(sListen,(struct sockaddr *)&local,sizeof(local))==SOCKET_ERROR) //监听套接字与本地IP绑定
...{
cout<<"bind() failed :"<<WSAGetLastError()<<' ';
exit(); //退出动作
return 1;
}
listen(sListen,32);//服务器监听,32为连接队列的长度
cout<<"服务器已启动"<<' ';
while(1) //循环等待进入的客户端连接,一旦检查到连接,创建线程并且传送句柄
...{
iAddrSize=sizeof(client);
sClient=accept(sListen,(struct sockaddr*)&client,&iAddrSize);
if(sClient==INVALID_SOCKET)
...{
cout<<"accept() faild: "<<WSAGetLastError()<<' ';
break;
}
cout<<"Accepted client: "<<inet_ntoa(client.sin_addr)<<":"<<ntohs(client.sin_port)<<' ';
hThread=CreateThread(NULL,0,ClientThread,(LPVOID)sClient,0,&dwThreadId); //启动线程
if(hThread==NULL)
...{
cout<<"CreateThread() failed: "<<GetLastError()<<' ';
break;
}
CloseHandle(hThread);
}
closesocket(sListen);//关闭监听套接
WSACleanup();//WSACleanup terminates Windows Sockets operations for all threads
exit(); //退出动作
return 0;
}
void exit() // 退出动作
... {
cout<<"按任意键退出"<<" ";
if(getchar()) //防止cmd立即退出
return;
}
bool sendList(LPVOID lpParam,vector < _finddata_t > & fileDec,vector < _finddata_t > & dirDec) // 发送文件列表
... {
SOCKET sock=(SOCKET)lpParam; //客户端套接
char Buffer[DEFAULT_BUFFER]; //缓冲区
struct _finddata_t fileinfo; //文件信息
int ret;
long hFile =0; //文件句柄
int j=0;
char tpath[1024];
strcpy(tpath,path);
strcat(tpath,"/*.*");
if((hFile=_findfirst(tpath,&fileinfo)) != -1) //检查是不是目录
...{
do
...{
if ((fileinfo.attrib & _A_SUBDIR))
...{
if (strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0) //如果是,再检查是不是 . 或 ..
dirDec.push_back( fileinfo ); //把文件夹信息放入目录容器
}
else //如果不是,进行迭代
...{
fileDec.push_back( fileinfo ); //把文件信息放入文件容器
}
} while (_findnext( hFile, &fileinfo ) == 0);
_findclose(hFile);
}
else
...{
cout<<path<<" 不是一个目录"<<' ';
return false;
}
fd_set sf; //The fd_set structure is used by various Windows Sockets functions and service providers, such as the select function,
//to place sockets into a "set" for various purposes, such as testing a given socket for readability using the readfds parameter of
//the select function
sf.fd_count=0;
sf.fd_array[sf.fd_count++]=sock;
timeval to; //The timeval structure is used to specify time values
to.tv_sec=60; //60s超时
to.tv_usec=0; //毫秒
for (j=0;j<dirDec.size();++j) //首先发送文件夹信息
...{
for(int i=0;i<2;i++)
...{
if(i==0)
...{
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock,dirDec[j].name,DEFAULT_BUFFER,0); //发送文件夹名
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
else
...{
strcpy(Buffer,asctime( gmtime( &dirDec[j].time_create ) )); //把timeval转换为string
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock, Buffer,DEFAULT_BUFFER,0); //发送文件夹最后修改时间
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
}
}
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock," ",DEFAULT_BUFFER,0);//发送结束标志
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
for ( j=0; j<fileDec.size(); ++j) //然后发送文件信息
...{
for(int i=0;i<3;i++)
...{
if(i==0)
...{
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock,fileDec[j].name,DEFAULT_BUFFER,0); //发送文件名
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
else if(i==1)
...{
itoa(fileDec[j].size, Buffer,10); //把long转为string
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock, Buffer,DEFAULT_BUFFER,0); //发送文件大小
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
else
...{
strcpy( Buffer,asctime( gmtime( &fileDec[j].time_create ) )); //把timeval转换为string
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock,Buffer,DEFAULT_BUFFER,0); //发送文件最后修改时间
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
}
}
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock," ",DEFAULT_BUFFER,0);//发送结束标志
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
return true;
}
bool down(LPVOID lpParam,vector < _finddata_t > & fileDec) // 发送文件
... {
SOCKET sock=(SOCKET)lpParam; //客户端套接
int ret;
char Buffer[DEFAULT_BUFFER]; //缓冲区
fd_set sf,rf; //The fd_set structure is used by various Windows Sockets functions and service providers, such as the select function,
//to place sockets into a "set" for various purposes, such as testing a given socket for readability using the readfds parameter of
//the select function
//sf check for writability,rf check for readability
rf.fd_count=0;
rf.fd_array[rf.fd_count++]=sock;
timeval to; //The timeval structure is used to specify time values
to.tv_sec=60; //60s超时
to.tv_usec=0; //毫秒
if(select(0,&rf,NULL,NULL,&to)) //checked for readability,接收要发送的文件目录信息
...{
ret=recv(sock,Buffer,DEFAULT_BUFFER,0);
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"recv() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
int i = atoi(Buffer); //把string转为int
char tpath[1024];
strcpy(tpath,path);
strcat(tpath,"/");
strcat(tpath,fileDec[--i].name);
fstream instuf(tpath,ios::in|ios::binary); //以二字制只读方式打开要发送的文件
if(!instuf)
...{
cerr<<"File could not be open."<<' ';
return false;
}
instuf.seekp(0,ios::end); //计算文件的大小
unsigned long posEnd=instuf.tellp();
instuf.seekp(0,ios::beg);
cout<<"Sending file "<<tpath<<' ';
sf.fd_count=0;
sf.fd_array[sf.fd_count++]=sock;
while(posEnd>0)
...{
if(posEnd>DEFAULT_BUFFER) //当文件大小大于缓冲区时,在文件中读取缓冲区大小的文件发送
...{
instuf.read((char*)Buffer,DEFAULT_BUFFER);
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock,Buffer,DEFAULT_BUFFER,0);
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
posEnd-=DEFAULT_BUFFER;
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
else
...{
instuf.read((char*)Buffer,posEnd); //当文件大小小于缓冲区时,文件全部发送
if(select(0,NULL,&sf,NULL,&to)) /**/////checked for writability
...{
ret=send(sock,Buffer,DEFAULT_BUFFER,0);
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
posEnd=0;
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
}
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock," ",DEFAULT_BUFFER,0); //发送结束标志
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
cout<<"Send file "<<tpath<<" completely"<<' ';
instuf.close();
return true;
}
DWORD WINAPI ClientThread(LPVOID lpParam) // 线程方式调用,并且处理给定客户端连接,传递参数从accept函数调用中返回的套接
... {
SOCKET sock=(SOCKET)lpParam; //客户端套接
vector<_finddata_t> fileDec; // 文件容器
vector<_finddata_t> dirDec; //目录容器
char Buffer[DEFAULT_BUFFER]; //缓冲区
int ret;
while(ret=recv(sock,Buffer,DEFAULT_BUFFER,0)) //接收客户端发送的命令
...{
if(ret==0)
return 1;
else if(ret==SOCKET_ERROR)
...{
return 1;
}
if(strcmp(Buffer,"LIST")==0) //服务器接受"LIST"命令,则显示文件列表
...{
fileDec.clear();
dirDec.clear();
if(!sendList(lpParam,fileDec,dirDec))
return 1;
}
else if(strcmp(Buffer,"DOWN")==0)
...{
if(!down(lpParam,fileDec))
return 1;
}
}
return 0;
}
void setDirectory() // 设置FTP服务器目录
... {
char c;
_finddata_t fileinfo; //文件信息
long hFile;//文件句柄
bool set=false;
cout<<"输入FTP服务器目录,默认为C:,如果要保持默认目录,请直接输入ENTER:"<<' ';
while(!set)
...{
int i=0;
while(c=getchar())
...{
if(c==' ')
break;
else
path[i]=c;
i++;
if(strlen(path)>=1024)
break;
}
if(i==0)
...{
strcpy(path,DEFAULT_PATH);
}
else
...{
--i;
while(path[i]=='/')
...{
path[i--]='
// 需在项目设置 链接中添加ws2_32.lib
#include " stdafx.h "
#include < winsock2.h >
#include < iostream >
#include < fstream >
#include < io.h >
#include < string >
#include < vector >
#include < iomanip >
#include < ctime >
using namespace std;
#define DEFAULT_PORT 2100 // 默认服务器端口
#define DEFAULT_BUFFER 4096 // 默认缓冲区大小
char path[ 1024 ]; // FTP服务器的服务目录
# define DEFAULT_PATH " C: " // 默认目录
bool sendList(LPVOID ,vector < _finddata_t > & ,vector < _finddata_t > & ); // 发送文件列表
bool down(LPVOID,vector < _finddata_t > & ); // 发送文件
DWORD WINAPI ClientThread(LPVOID ); // 服务器线程
void setDirectory(); // 设置FTP服务器的服务目录
void exit(); // 退出动作
int main()
... {
setDirectory();//设置FTP服务器目录
WSADATA wsd; //The WSADATA structure contains information about the Windows Sockets implementation
SOCKET sListen,sClient;//服务器和客户端的套接
int iAddrSize;
HANDLE hThread;
DWORD dwThreadId;
struct sockaddr_in local,client; // address information
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)
...{
cout<<"Faile to load Winsock!"<<' ';
exit(); //退出动作
return 1;
}
sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);//创建监听套接字
if(sListen==SOCKET_ERROR)
...{
cout<<"socket() failed: "<<WSAGetLastError()<<' ';
exit(); //退出动作
return 1;
}
local.sin_addr.s_addr=htonl(INADDR_ANY);
local.sin_family=AF_INET;
local.sin_port=htons(DEFAULT_PORT);
if(bind(sListen,(struct sockaddr *)&local,sizeof(local))==SOCKET_ERROR) //监听套接字与本地IP绑定
...{
cout<<"bind() failed :"<<WSAGetLastError()<<' ';
exit(); //退出动作
return 1;
}
listen(sListen,32);//服务器监听,32为连接队列的长度
cout<<"服务器已启动"<<' ';
while(1) //循环等待进入的客户端连接,一旦检查到连接,创建线程并且传送句柄
...{
iAddrSize=sizeof(client);
sClient=accept(sListen,(struct sockaddr*)&client,&iAddrSize);
if(sClient==INVALID_SOCKET)
...{
cout<<"accept() faild: "<<WSAGetLastError()<<' ';
break;
}
cout<<"Accepted client: "<<inet_ntoa(client.sin_addr)<<":"<<ntohs(client.sin_port)<<' ';
hThread=CreateThread(NULL,0,ClientThread,(LPVOID)sClient,0,&dwThreadId); //启动线程
if(hThread==NULL)
...{
cout<<"CreateThread() failed: "<<GetLastError()<<' ';
break;
}
CloseHandle(hThread);
}
closesocket(sListen);//关闭监听套接
WSACleanup();//WSACleanup terminates Windows Sockets operations for all threads
exit(); //退出动作
return 0;
}
void exit() // 退出动作
... {
cout<<"按任意键退出"<<" ";
if(getchar()) //防止cmd立即退出
return;
}
bool sendList(LPVOID lpParam,vector < _finddata_t > & fileDec,vector < _finddata_t > & dirDec) // 发送文件列表
... {
SOCKET sock=(SOCKET)lpParam; //客户端套接
char Buffer[DEFAULT_BUFFER]; //缓冲区
struct _finddata_t fileinfo; //文件信息
int ret;
long hFile =0; //文件句柄
int j=0;
char tpath[1024];
strcpy(tpath,path);
strcat(tpath,"/*.*");
if((hFile=_findfirst(tpath,&fileinfo)) != -1) //检查是不是目录
...{
do
...{
if ((fileinfo.attrib & _A_SUBDIR))
...{
if (strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0) //如果是,再检查是不是 . 或 ..
dirDec.push_back( fileinfo ); //把文件夹信息放入目录容器
}
else //如果不是,进行迭代
...{
fileDec.push_back( fileinfo ); //把文件信息放入文件容器
}
} while (_findnext( hFile, &fileinfo ) == 0);
_findclose(hFile);
}
else
...{
cout<<path<<" 不是一个目录"<<' ';
return false;
}
fd_set sf; //The fd_set structure is used by various Windows Sockets functions and service providers, such as the select function,
//to place sockets into a "set" for various purposes, such as testing a given socket for readability using the readfds parameter of
//the select function
sf.fd_count=0;
sf.fd_array[sf.fd_count++]=sock;
timeval to; //The timeval structure is used to specify time values
to.tv_sec=60; //60s超时
to.tv_usec=0; //毫秒
for (j=0;j<dirDec.size();++j) //首先发送文件夹信息
...{
for(int i=0;i<2;i++)
...{
if(i==0)
...{
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock,dirDec[j].name,DEFAULT_BUFFER,0); //发送文件夹名
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
else
...{
strcpy(Buffer,asctime( gmtime( &dirDec[j].time_create ) )); //把timeval转换为string
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock, Buffer,DEFAULT_BUFFER,0); //发送文件夹最后修改时间
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
}
}
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock," ",DEFAULT_BUFFER,0);//发送结束标志
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
for ( j=0; j<fileDec.size(); ++j) //然后发送文件信息
...{
for(int i=0;i<3;i++)
...{
if(i==0)
...{
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock,fileDec[j].name,DEFAULT_BUFFER,0); //发送文件名
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
else if(i==1)
...{
itoa(fileDec[j].size, Buffer,10); //把long转为string
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock, Buffer,DEFAULT_BUFFER,0); //发送文件大小
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
else
...{
strcpy( Buffer,asctime( gmtime( &fileDec[j].time_create ) )); //把timeval转换为string
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock,Buffer,DEFAULT_BUFFER,0); //发送文件最后修改时间
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
}
}
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock," ",DEFAULT_BUFFER,0);//发送结束标志
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
return true;
}
bool down(LPVOID lpParam,vector < _finddata_t > & fileDec) // 发送文件
... {
SOCKET sock=(SOCKET)lpParam; //客户端套接
int ret;
char Buffer[DEFAULT_BUFFER]; //缓冲区
fd_set sf,rf; //The fd_set structure is used by various Windows Sockets functions and service providers, such as the select function,
//to place sockets into a "set" for various purposes, such as testing a given socket for readability using the readfds parameter of
//the select function
//sf check for writability,rf check for readability
rf.fd_count=0;
rf.fd_array[rf.fd_count++]=sock;
timeval to; //The timeval structure is used to specify time values
to.tv_sec=60; //60s超时
to.tv_usec=0; //毫秒
if(select(0,&rf,NULL,NULL,&to)) //checked for readability,接收要发送的文件目录信息
...{
ret=recv(sock,Buffer,DEFAULT_BUFFER,0);
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"recv() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
int i = atoi(Buffer); //把string转为int
char tpath[1024];
strcpy(tpath,path);
strcat(tpath,"/");
strcat(tpath,fileDec[--i].name);
fstream instuf(tpath,ios::in|ios::binary); //以二字制只读方式打开要发送的文件
if(!instuf)
...{
cerr<<"File could not be open."<<' ';
return false;
}
instuf.seekp(0,ios::end); //计算文件的大小
unsigned long posEnd=instuf.tellp();
instuf.seekp(0,ios::beg);
cout<<"Sending file "<<tpath<<' ';
sf.fd_count=0;
sf.fd_array[sf.fd_count++]=sock;
while(posEnd>0)
...{
if(posEnd>DEFAULT_BUFFER) //当文件大小大于缓冲区时,在文件中读取缓冲区大小的文件发送
...{
instuf.read((char*)Buffer,DEFAULT_BUFFER);
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock,Buffer,DEFAULT_BUFFER,0);
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
posEnd-=DEFAULT_BUFFER;
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
else
...{
instuf.read((char*)Buffer,posEnd); //当文件大小小于缓冲区时,文件全部发送
if(select(0,NULL,&sf,NULL,&to)) /**/////checked for writability
...{
ret=send(sock,Buffer,DEFAULT_BUFFER,0);
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
posEnd=0;
}
else
...{
cout<<"time out"<<' ';
return false;
}
}
}
if(select(0,NULL,&sf,NULL,&to)) //checked for writability
...{
ret=send(sock," ",DEFAULT_BUFFER,0); //发送结束标志
if(ret==0)
return false;
else if(ret==SOCKET_ERROR)
...{
cout<<"send() faild: "<<WSAGetLastError()<<' ';
return false;
}
}
else
...{
cout<<"time out"<<' ';
return false;
}
cout<<"Send file "<<tpath<<" completely"<<' ';
instuf.close();
return true;
}
DWORD WINAPI ClientThread(LPVOID lpParam) // 线程方式调用,并且处理给定客户端连接,传递参数从accept函数调用中返回的套接
... {
SOCKET sock=(SOCKET)lpParam; //客户端套接
vector<_finddata_t> fileDec; // 文件容器
vector<_finddata_t> dirDec; //目录容器
char Buffer[DEFAULT_BUFFER]; //缓冲区
int ret;
while(ret=recv(sock,Buffer,DEFAULT_BUFFER,0)) //接收客户端发送的命令
...{
if(ret==0)
return 1;
else if(ret==SOCKET_ERROR)
...{
return 1;
}
if(strcmp(Buffer,"LIST")==0) //服务器接受"LIST"命令,则显示文件列表
...{
fileDec.clear();
dirDec.clear();
if(!sendList(lpParam,fileDec,dirDec))
return 1;
}
else if(strcmp(Buffer,"DOWN")==0)
...{
if(!down(lpParam,fileDec))
return 1;
}
}
return 0;
}
void setDirectory() // 设置FTP服务器目录
... {
char c;
_finddata_t fileinfo; //文件信息
long hFile;//文件句柄
bool set=false;
cout<<"输入FTP服务器目录,默认为C:,如果要保持默认目录,请直接输入ENTER:"<<' ';
while(!set)
...{
int i=0;
while(c=getchar())
...{
if(c==' ')
break;
else
path[i]=c;
i++;
if(strlen(path)>=1024)
break;
}
if(i==0)
...{
strcpy(path,DEFAULT_PATH);
}
else
...{
--i;
while(path[i]=='/')
...{
path[i--]='