2015-01-17 20:00:57|?次阅读|上传:wustguangh【已有?条评论】发表评论
关键词:C/C++, 网络通信|来源:唯设编程网
//删除指定FTP目录
int CFTP::ftp_rmdir( const char* dir )
{
sprintf_s(m_cmd,"RMD %s
",dir);
int err = ftp_sendcmd(m_cmd,m_resp,sizeof(m_resp));
if(err)
return -1;
//得到返回码
int code = get_state_code(m_resp);
//250 RMD command successful.
if(code != 250)
return -1;
return 0;
}
删除FTP目录使用的命令是RMD。
//改变数据传输模式为PASV,并创建数据传输SOCKET
int CFTP::ftp_setpasv()
{
sprintf_s(m_cmd,"PASV
");
int err = ftp_sendcmd(m_cmd,m_resp,sizeof(m_resp));
if(err)
return -1;
//得到返回码
int code = get_state_code(m_resp);
//227 Entering Passive Mode (127,0,0,1,32,137).
if(code != 227)
return -1;
m_sockdata = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
unsigned int v[6]={0};
union {
struct sockaddr sa;
struct sockaddr_in in;
} sin;
sscanf_s(m_resp,"%*[^(](%u,%u,%u,%u,%u,%u",&v[2],&v[3],&v[4],&v[5],&v[0],&v[1]);
sin.sa.sa_family = AF_INET;
sin.sa.sa_data[2] = v[2];
sin.sa.sa_data[3] = v[3];
sin.sa.sa_data[4] = v[4];
sin.sa.sa_data[5] = v[5];
sin.sa.sa_data[0] = v[0];
sin.sa.sa_data[1] = v[1];
int on =1;
if (setsockopt(m_sockdata,SOL_SOCKET,SO_REUSEADDR,
(const char*) &on,sizeof(on)) == -1)
{
perror("setsockopt");
closesocket(m_sockdata);
return -1;
}
struct linger lng = { 0, 0 };
if (setsockopt(m_sockdata,SOL_SOCKET,SO_LINGER,
(const char*) &lng,sizeof(lng)) == -1)
{
perror("setsockopt");
closesocket(m_sockdata);
return -1;
}
err = connect(m_sockdata,(sockaddr*)&sin,sizeof(sin));
if(err)
return -1;
return 0;
}
上传/下载文件需要将数据传输模式设置为PASV,这可以通过命令PASV完成,除此之外,该函数还创建了数据传输用的SOCKET,并将该SOCKET与服务器建立连接。
//上传目录
int CFTP::ftp_upload_dir( const char* localpath,const char* remotepath,size_t buf_size)
{
//进入FTP目录
int err = ftp_cd(remotepath);
if(err){
ftp_mkdir(remotepath);
}
WCHAR szFind[MAX_PATH] = {0};
//搜索条件
USES_CONVERSION;
wcscpy(szFind,A2W(localpath));
wcscat(szFind,A2W("*.*"));
WIN32_FIND_DATA FindFileData;
HANDLE hFind = ::FindFirstFile(szFind,&FindFileData);
if(INVALID_HANDLE_VALUE == hFind){
std::cout<<"对应目录不存在!"<<std::endl;
return -1;
}
//查找的文件
WCHAR szFile[MAX_PATH] = {0};
do{
memset(szFile,0,sizeof(szFile));
wcscpy(szFile,A2W(localpath));
wcscat(szFile,A2W(""));
wcscat(szFile,FindFileData.cFileName);
//目录
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
if(FindFileData.cFileName[0] != '.'){
WCHAR szRemotePath[MAX_PATH] = {0};
wcscpy(szRemotePath,A2W(remotepath));
wcscat(szRemotePath,A2W("/"));
wcscat(szRemotePath,FindFileData.cFileName);
//上传子目录
ftp_upload_dir(W2A(szFile),W2A(szRemotePath),buf_size);
}
}//文件
else{
ftp_upload(W2A(szFile),remotepath,W2A(FindFileData.cFileName),buf_size);
}
}while(FindNextFile(hFind,&FindFileData));
//关闭文件查找句柄
FindClose(hFind);
return 0;
}
该方法实现将本地指定目录的内容上传到FTP指定的目录,并且使用递归方法将目录的子目录也上传到FTP服务器。Windows目录内容的便利使用的方法主要有两个:FindFirstFile和FindNextFile,FindFirstFile方法的第一个参数是WCHAR,第二个参数是WIN32_FIND_DATA类型的数据指针,存储查找结果,这个方法返回一个HANDLE类型的数据,FindNextFile则使用这个句柄作为第一个参数,第二个参数依然是WIN32_FIND_DATA类型的数据指针,保存查询结果。使用完成后,记得调用FindClose将对应句柄关闭。