您的位置:首页 > 编程语言 > C语言/C++

C++实现ftp客户端

2014-09-11 16:09 387 查看
#ifndef CLIENT_H_
#define CLIENT_H_

#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <netdb.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <string>
#include <list>

#define INVALID_SOCKET				-1
#define FTP_API						int
#define MAX_PATH					260
#define trace						printf

#define FTP_PARAM_BASE
#define FTP_DEFAULT_PORT			"21"							//FTP默认端口号
#define FTP_DEFAULT_BUFFER			1024*4							//FTP下载缓冲默认大小
#define FTP_DEFAULT_PATH			"/mnt/dvs/"						//FTP默认保存路径

#define FTP_COMMAND_BASE			1000
#define FTP_COMMAND_END				FTP_COMMAND_BASE + 30
#define FTP_COMMAND_USERNAME		FTP_COMMAND_BASE + 1			//用户名
#define FTP_COMMAND_PASSWORD		FTP_COMMAND_BASE + 2			//密码
#define FTP_COMMAND_QUIT			FTP_COMMAND_BASE + 3			//退出
#define FTP_COMMAND_CURRENT_PATH	FTP_COMMAND_BASE + 4			// 获取文件路径
#define FTP_COMMAND_TYPE_MODE		FTP_COMMAND_BASE + 5			// 改变传输模式
#define FTP_COMMAND_PSAV_MODE		FTP_COMMAND_BASE + 6			// 被动端口模式
#define FTP_COMMAND_DIR				FTP_COMMAND_BASE + 7			// 获取文件列表
#define FTP_COMMAND_CHANGE_DIRECTORY FTP_COMMAND_BASE + 8			// 改变路径
#define FTP_COMMAND_DELETE_FILE		FTP_COMMAND_BASE + 9			// 删除文件
#define FTP_COMMAND_DELETE_DIRECTORY FTP_COMMAND_BASE + 10			// 删除目录/文件夹
#define FTP_COMMAND_CREATE_DIRECTORY FTP_COMMAND_BASE + 11			// 创建目录/文件夹
#define FTP_COMMAND_RENAME_BEGIN    FTP_COMMAND_BASE  +12			// 开始重命名
#define FTP_COMMAND_RENAME_END      FTP_COMMAND_BASE + 13			// 重命名结束
#define FTP_COMMAND_FILE_SIZE		FTP_COMMAND_BASE + 14			// 获取文件大小
#define FTP_COMMAND_DOWNLOAD_POS	FTP_COMMAND_BASE + 15			// 下载文件从指定位置开始
#define FTP_COMMAND_DOWNLOAD_FILE	FTP_COMMAND_BASE + 16			// 下载文件
#define FTP_COMMAND_UPLOAD_FILE		FTP_COMMAND_BASE + 17			// 上传文件
#define FTP_COMMAND_APPEND_FILE		FTP_COMMAND_BASE + 18			// 追加上载文件

/*		  登陆步骤
login2Server
|
inputUserName
|
inputPassWord
|
具体操作
|
quit
*/

class CFTPManager
{
public :

enum type {
binary = 0x31,
ascii,
};

CFTPManager(void);

virtual ~CFTPManager(void);

// ! 登陆服务器
FTP_API login2Server(const std::string &serverIP);

// !输入用户名
FTP_API inputUserName(const std::string &userName);

// !输入密码
FTP_API inputPassWord(const std::string &password);

// !退出FTP
FTP_API quitServer(void);

// !命令: PWD
const std::string PWD();

// !设置传输格式 2进制  还是ascii方式传输
FTP_API setTransferMode(type mode);

// !设置为被动模式
const std::string Pasv();

// ! 命令: DIR
const std::string Dir(const std::string &path);

// !命令 : CD
FTP_API CD(const std::string &path);

// !删除文件
FTP_API DeleteFile(const std::string &strRemoteFile);

// ! 删除文件夹/目录
FTP_API DeleteDirectory(const std::string &strRemoteDir);

// ! 创建目录/文件夹
FTP_API CreateDirectory(const std::string &strRemoteDir);

// !重命名
FTP_API Rename(const std::string &strRemoteFile, const std::string &strNewFile);

// !获取文件大小
long getFileLength(const std::string &strRemoteFile);

// !关闭连接
void Close(int sock);

// 下载文件
FTP_API Get(const std::string &strRemoteFile, const std::string &strLocalFile);

// 上载文件  支持断电传送方式
FTP_API Put(const std::string &strRemoteFile, const std::string &strLocalFile);

private:
// !合成发送到服务器的命令
const std::string parseCommand(const unsigned int command, const std::string &strParam);

// ! 建立连接
FTP_API Connect(int socketfd, const std::string &serverIP, unsigned int nPort);

// ! 返回服务器信息
const std::string serverResponse(int sockfd);

// !获取服务器数据
FTP_API getData(int fd, char *strBuf, unsigned long length);

// !发送命令
FTP_API Send(int fd, const std::string &cmd);

// !发送命令
FTP_API Send(int fd, const char *cmd, const size_t len);

// !建立数据连接
FTP_API createDataLink(int data_fd);

// !解析PASV模式返回的字符串获取FTP端口号和FTP服务器IP
FTP_API ParseString(std::list<std::string> strArray, unsigned long & nPort ,std::string & strServerIp);

// 打开本地文件
FILE *createLocalFile(const std::string &strLocalFile);

// 下载文件
FTP_API downLoad(const std::string &strRemoteFile, const std::string &strLocalFile, const int pos = 0, const unsigned int length = 0);

// 解析返回ftp命令的值
FTP_API parseResponse(const std::string &str);

private:
//!控制连接套接字
int		m_cmdSocket;

// !当前用户名
std::string m_strUserName;

// !当前用户密码
std::string m_strPassWord;

// !服务器的IP
std::string m_strServerIP;

// !服务器Port
unsigned int m_nServerPort;

// !服务器回应信息缓存
std::string m_strResponse;

// !保存命令参数
std::string m_commandStr;

// !当前使用的命令参数
unsigned int m_nCurrentCommand;

// !是否登陆标志。
bool	m_bLogin;
};

#endif


#include "../Source/FTPManager.h"

static int SplitString( std::string strSrc, std::list<std::string> &strArray , std::string strFlag)
{
int pos = 1;

while((pos = (int)strSrc.find_first_of(strFlag.c_str())) > 0)
{
strArray.insert(strArray.end(), strSrc.substr(0 , pos));
strSrc = strSrc.substr(pos + 1, strSrc.length() - pos - 1);
}

strArray.insert(strArray.end(), strSrc.substr(0, strSrc.length()));

return 0;
}

CFTPManager::CFTPManager(void): m_bLogin(false)
{
m_cmdSocket = socket(AF_INET, SOCK_STREAM, 0);

}

CFTPManager::~CFTPManager(void)
{
std::string strCmdLine = parseCommand(FTP_COMMAND_QUIT, "");

Send(m_cmdSocket, strCmdLine.c_str());
close(m_cmdSocket);
m_bLogin = false;
}

FTP_API CFTPManager::login2Server(const std::string &serverIP)
{
std::string strPort;
int pos = serverIP.find_first_of(":");

if (pos > 0)
{
strPort = serverIP.substr(pos + 1, serverIP.length() - pos);
}
else
{
pos = serverIP.length();
strPort = FTP_DEFAULT_PORT;
}

m_strServerIP = serverIP.substr(0, pos);
m_nServerPort = atol(strPort.c_str());

trace("IP: %s port: %d\n", m_strServerIP.c_str(), m_nServerPort);

if (Connect(m_cmdSocket, m_strServerIP, m_nServerPort) < 0)
{

return -1;
}

m_strResponse = serverResponse(m_cmdSocket);
printf("@@@@Response: %s", m_strResponse.c_str());

return	parseResponse(m_strResponse);
}

FTP_API CFTPManager::inputUserName(const std::string &userName)
{
std::string strCommandLine = parseCommand(FTP_COMMAND_USERNAME, userName);

m_strUserName = userName;

if (Send(m_cmdSocket, strCommandLine) < 0)
{
return -1;
}

m_strResponse = serverResponse(m_cmdSocket);
printf("Response: %s\n", m_strResponse.c_str());

return parseResponse(m_strResponse);
}

FTP_API CFTPManager::inputPassWord(const std::string &password)
{
std::string strCmdLine = parseCommand(FTP_COMMAND_PASSWORD, password);

m_strPassWord = password;
if (Send(m_cmdSocket, strCmdLine) < 0)
{
return -1;
}
else
{
m_bLogin = true;

m_strResponse = serverResponse(m_cmdSocket);
printf("Response: %s\n", m_strResponse.c_str());

return parseResponse(m_strResponse);
}
}

FTP_API CFTPManager::quitServer(void)
{
std::string strCmdLine = parseCommand(FTP_COMMAND_QUIT, "");
if (Send(m_cmdSocket, strCmdLine) < 0)
{
return -1;
}
else
{
m_strResponse = serverResponse(m_cmdSocket);
printf("Response: %s\n", m_strResponse.c_str());

return parseResponse(m_strResponse);
}

}

const std::string CFTPManager::PWD()
{
std::string strCmdLine = parseCommand(FTP_COMMAND_CURRENT_PATH, "");

if (Send(m_cmdSocket, strCmdLine.c_str()) < 0)
{
return "";
}
else
{
return serverResponse(m_cmdSocket);
}
}

FTP_API CFTPManager::setTransferMode(type mode)
{
std::string strCmdLine;

switch (mode)
{
case binary:
strCmdLine = parseCommand(FTP_COMMAND_TYPE_MODE, "I");
break;
case ascii:
strCmdLine = parseCommand(FTP_COMMAND_TYPE_MODE, "A");
break;
default:
break;
}

if (Send(m_cmdSocket, strCmdLine.c_str()) < 0)
{
assert(false);
}
else
{
m_strResponse  = serverResponse(m_cmdSocket);
printf("@@@@Response: %s", m_strResponse.c_str());

return parseResponse(m_strResponse);
}
}

const std::string CFTPManager::Pasv()
{
std::string strCmdLine = parseCommand(FTP_COMMAND_PSAV_MODE, "");

if (Send(m_cmdSocket, strCmdLine.c_str()) < 0)
{
return "";
}
else
{
m_strResponse = serverResponse(m_cmdSocket);

return m_strResponse;
}
}

const std::string CFTPManager::Dir(const std::string &path)
{
int dataSocket = socket(AF_INET, SOCK_STREAM, 0);

if (createDataLink(dataSocket) < 0)
{
return "";
}
// 数据连接成功
std::string strCmdLine = parseCommand(FTP_COMMAND_DIR, path);

if (Send(m_cmdSocket, strCmdLine) < 0)
{
trace("@@@@Response: %s\n", serverResponse(m_cmdSocket).c_str());
close(dataSocket);
return "";
}
else
{
trace("@@@@Response: %s\n", serverResponse(m_cmdSocket).c_str());
m_strResponse = serverResponse(dataSocket);

trace("@@@@Response: \n%s\n", m_strResponse.c_str());
close(dataSocket);

return m_strResponse;
}

}

FTP_API CFTPManager::CD(const std::string &path)
{
assert(m_cmdSocket != INVALID_SOCKET);

std::string strCmdLine = parseCommand(FTP_COMMAND_CHANGE_DIRECTORY, path);

if (Send(m_cmdSocket, strCmdLine) < 0)
{
return -1;
}

m_strResponse = serverResponse(m_cmdSocket);

trace("@@@@Response: %s\n", m_strResponse.c_str());
return parseResponse(m_strResponse);
}

FTP_API CFTPManager::DeleteFile(const std::string &strRemoteFile)
{
assert(m_cmdSocket != INVALID_SOCKET);

std::string strCmdLine = parseCommand(FTP_COMMAND_DELETE_FILE, strRemoteFile);

if (Send(m_cmdSocket, strCmdLine) < 0)
{
return -1;
}

m_strResponse = serverResponse(m_cmdSocket);
printf("@@@@Response: %s\n", m_strResponse.c_str());
return parseResponse(m_strResponse);
}

FTP_API CFTPManager::DeleteDirectory(const std::string &strRemoteDir)
{
assert(m_cmdSocket != INVALID_SOCKET);

std::string strCmdLine = parseCommand(FTP_COMMAND_DELETE_DIRECTORY, strRemoteDir);

if (Send(m_cmdSocket, strCmdLine) < 0)
{
return -1;
}

m_strResponse = serverResponse(m_cmdSocket);

trace("@@@@Response: %s\n", m_strResponse.c_str());
return parseResponse(m_strResponse);
}

FTP_API CFTPManager::CreateDirectory(const std::string &strRemoteDir)
{
assert(m_cmdSocket != INVALID_SOCKET);

std::string strCmdLine = parseCommand(FTP_COMMAND_CREATE_DIRECTORY, strRemoteDir);

if (Send(m_cmdSocket, strCmdLine) < 0)
{
return -1;
}

m_strResponse = serverResponse(m_cmdSocket);

trace("@@@@Response: %s\n", m_strResponse.c_str());
return parseResponse(m_strResponse);
}

FTP_API CFTPManager::Rename(const std::string &strRemoteFile, const std::string &strNewFile)
{
assert(m_cmdSocket != INVALID_SOCKET);

std::string strCmdLine = parseCommand(FTP_COMMAND_RENAME_BEGIN, strRemoteFile);
Send(m_cmdSocket, strCmdLine);
trace("@@@@Response: %s\n", serverResponse(m_cmdSocket).c_str());

Send(m_cmdSocket, parseCommand(FTP_COMMAND_RENAME_END, strNewFile));

m_strResponse = serverResponse(m_cmdSocket);
trace("@@@@Response: %s\n", m_strResponse.c_str());
return parseResponse(m_strResponse);
}

long CFTPManager::getFileLength(const std::string &strRemoteFile)
{
assert(m_cmdSocket != INVALID_SOCKET);

std::string strCmdLine = parseCommand(FTP_COMMAND_FILE_SIZE, strRemoteFile);

if (Send(m_cmdSocket, strCmdLine) < 0)
{
return -1;
}

m_strResponse = serverResponse(m_cmdSocket);

trace("@@@@Response: %s\n", m_strResponse.c_str());

std::string strData = m_strResponse.substr(0, 3);
unsigned long val = atol(strData.c_str());

if (val == 213)
{
strData = m_strResponse.substr(4);
trace("strData: %s\n", strData.c_str());
val = atol(strData.c_str());

return val;
}

return -1;
}

void CFTPManager::Close(int sock)
{
shutdown(sock, SHUT_RDWR);
close(sock);
sock = INVALID_SOCKET;
}

FTP_API CFTPManager::Get(const std::string &strRemoteFile, const std::string &strLocalFile)
{
return downLoad(strRemoteFile, strLocalFile);
}

FTP_API CFTPManager::Put(const std::string &strRemoteFile, const std::string &strLocalFile)
{
std::string strCmdLine;
const unsigned long dataLen = FTP_DEFAULT_BUFFER;
char strBuf[dataLen] = {0};
unsigned long nSize = getFileLength(strRemoteFile);
unsigned long nLen = 0;
// 	struct stat sBuf;
//
// 	assert(stat(strLocalFile.c_str(), &sBuf) == 0);
// 	trace("size: %d\n", sBuf.st_size);

FILE *pFile = fopen(strLocalFile.c_str(), "rb");  // 以只读方式打开  且文件必须存在
assert(pFile != NULL);

int data_fd = socket(AF_INET, SOCK_STREAM, 0);
assert(data_fd != -1);

if (createDataLink(data_fd) < 0)
{
return -1;
}

if (nSize == -1)
{
strCmdLine = parseCommand(FTP_COMMAND_UPLOAD_FILE, strRemoteFile);
}
else
{
strCmdLine = parseCommand(FTP_COMMAND_APPEND_FILE, strRemoteFile);
}

if (Send(m_cmdSocket, strCmdLine) < 0)
{
Close(data_fd);
return -1;
}

trace("@@@@Response: %s\n", serverResponse(m_cmdSocket).c_str());

fseek(pFile, nSize, SEEK_SET);
while (!feof(pFile))
{
nLen = fread(strBuf, 1, dataLen, pFile);
if (nLen < 0)
{
break;
}

if (Send(data_fd, strBuf) < 0)
{
Close(data_fd);
return -1;
}
}

trace("@@@@Response: %s\n", serverResponse(data_fd).c_str());

Close(data_fd);
trace("@@@@Response: %s\n", serverResponse(m_cmdSocket).c_str());
fclose(pFile);

return 0;
}

const std::string CFTPManager::parseCommand(const unsigned int command, const std::string &strParam)
{
if (command < FTP_COMMAND_BASE || command > FTP_COMMAND_END)
{
return "";
}

std::string strCommandLine;

m_nCurrentCommand = command;
m_commandStr.clear();

switch (command)
{
case FTP_COMMAND_USERNAME:
strCommandLine = "USER ";
break;
case FTP_COMMAND_PASSWORD:
strCommandLine = "PASS ";
break;
case FTP_COMMAND_QUIT:
strCommandLine = "QUIT ";
break;
case FTP_COMMAND_CURRENT_PATH:
strCommandLine = "PWD ";
break;
case FTP_COMMAND_TYPE_MODE:
strCommandLine = "TYPE ";
break;
case FTP_COMMAND_PSAV_MODE:
strCommandLine = "PASV ";
break;
case FTP_COMMAND_DIR:
strCommandLine = "LIST ";
break;
case FTP_COMMAND_CHANGE_DIRECTORY:
strCommandLine = "CWD ";
break;
case FTP_COMMAND_DELETE_FILE:
strCommandLine = "DELE ";
break;
case FTP_COMMAND_DELETE_DIRECTORY:
strCommandLine = "RMD ";
break;
case FTP_COMMAND_CREATE_DIRECTORY:
strCommandLine = "MKD ";
break;
case FTP_COMMAND_RENAME_BEGIN:
strCommandLine = "RNFR ";
break;
case FTP_COMMAND_RENAME_END:
strCommandLine = "RNTO ";
break;
case FTP_COMMAND_FILE_SIZE:
strCommandLine = "SIZE ";
break;
case FTP_COMMAND_DOWNLOAD_FILE:
strCommandLine = "RETR ";
break;
case FTP_COMMAND_DOWNLOAD_POS:
strCommandLine = "REST ";
break;
case FTP_COMMAND_UPLOAD_FILE:
strCommandLine = "STOR ";
break;
case FTP_COMMAND_APPEND_FILE:
strCommandLine = "APPE ";
break;
default :
break;
}

strCommandLine += strParam;
strCommandLine += "\r\n";

m_commandStr = strCommandLine;
trace("parseCommand: %s\n", m_commandStr.c_str());

return m_commandStr;
}

FTP_API CFTPManager::Connect(int socketfd, const std::string &serverIP, unsigned int nPort)
{
if (socketfd == INVALID_SOCKET)
{
return -1;
}

unsigned int argp = 1;
int error = -1;
int len = sizeof(int);
struct sockaddr_in  addr;
bool ret = false;
timeval stime;
fd_set  set;

ioctl(socketfd, FIONBIO, &argp);  //设置为非阻塞模式

memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port	= htons(nPort);
addr.sin_addr.s_addr = inet_addr(serverIP.c_str());
bzero(&(addr.sin_zero), 8);

trace("Address: %s %d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

if (connect(socketfd, (struct sockaddr*)&addr, sizeof(struct sockaddr)) == -1)   //若直接返回 则说明正在进行TCP三次握手
{
stime.tv_sec = 20;  //设置为1秒超时
stime.tv_usec = 0;
FD_ZERO(&set);
FD_SET(socketfd, &set);

if (select(socketfd + 1, NULL, &set, NULL, &stime) > 0)   ///在这边等待 阻塞 返回可以读的描述符 或者超时返回0  或者出错返回-1
{
getsockopt(socketfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t*)&len);
if (error == 0)
{
ret = true;
}
else
{
ret = false;
}
}
}
else
{	trace("Connect Immediately!!!\n");
ret = true;
}

argp = 0;
ioctl(socketfd, FIONBIO, &argp);

if (!ret)
{
close(socketfd);
fprintf(stderr, "cannot connect server!!\n");
return -1;
}

//fprintf(stdout, "Connect!!!\n");

return 0;
}

const std::string CFTPManager::serverResponse(int sockfd)
{
if (sockfd == INVALID_SOCKET)
{
return "";
}

int nRet = -1;
char buf[MAX_PATH] = {0};

m_strResponse.clear();

while ((nRet = getData(sockfd, buf, MAX_PATH)) > 0)
{
buf[MAX_PATH - 1] = '\0';
m_strResponse += buf;
}

return m_strResponse;
}

FTP_API CFTPManager::getData(int fd, char *strBuf, unsigned long length)
{
assert(strBuf != NULL);

if (fd == INVALID_SOCKET)
{
return -1;
}

memset(strBuf, 0, length);
timeval stime;
int nLen;

stime.tv_sec = 1;
stime.tv_usec = 0;

fd_set	readfd;
FD_ZERO( &readfd );
FD_SET(fd, &readfd );

if (select(fd + 1, &readfd, 0, 0, &stime) > 0)
{
if ((nLen = recv(fd, strBuf, length, 0)) > 0)
{
return nLen;
}
else
{
return -2;
}
}
return 0;
}

FTP_API CFTPManager::Send(int fd, const std::string &cmd)
{
if (fd == INVALID_SOCKET)
{
return -1;
}

return Send(fd, cmd.c_str(), cmd.length());
}

FTP_API CFTPManager::Send(int fd, const char *cmd, const size_t len)
{
if((FTP_COMMAND_USERNAME != m_nCurrentCommand)
&&(FTP_COMMAND_PASSWORD != m_nCurrentCommand)
&&(!m_bLogin))
{
return -1;
}

timeval timeout;
timeout.tv_sec  = 1;
timeout.tv_usec = 0;

fd_set  writefd;
FD_ZERO(&writefd);
FD_SET(fd, &writefd);

if(select(fd + 1, 0, &writefd , 0 , &timeout) > 0)
{
size_t nlen  = len;
int nSendLen = 0;
while (nlen >0)
{
nSendLen = send(fd, cmd , (int)nlen , 0);

if(nSendLen == -1)
return -2;

nlen = nlen - nSendLen;
cmd +=  nSendLen;
}
return 0;
}
return -1;
}

FTP_API CFTPManager::createDataLink(int data_fd)
{
assert(data_fd != INVALID_SOCKET);

std::string strData;
unsigned long nPort = 0 ;
std::string strServerIp ;
std::list<std::string> strArray ;

std::string parseStr = Pasv();

if (parseStr.size() <= 0)
{
return -1;
}

//trace("parseInfo: %s\n", parseStr.c_str());

size_t nBegin = parseStr.find_first_of("(");
size_t nEnd	  = parseStr.find_first_of(")");
strData		  = parseStr.substr(nBegin + 1, nEnd - nBegin - 1);

//trace("ParseAfter: %s\n", strData.c_str());
if( SplitString( strData , strArray , "," ) <0)
return -1;

if( ParseString( strArray , nPort , strServerIp) < 0)
return -1;

//trace("nPort: %ld IP: %s\n", nPort, strServerIp.c_str());

if (Connect(data_fd, strServerIp, nPort) < 0)
{
return -1;
}

return 0;

}

FTP_API CFTPManager::ParseString(std::list<std::string> strArray, unsigned long & nPort ,std::string & strServerIp)
{
if (strArray.size() < 6 )
return -1 ;

std::list<std::string>::iterator citor;
citor = strArray.begin();
strServerIp = *citor;
strServerIp += ".";
citor ++;
strServerIp += *citor;
strServerIp += ".";
citor ++ ;
strServerIp += *citor;
strServerIp += ".";
citor ++ ;
strServerIp += *citor;
citor = strArray.end();
citor--;
nPort = atol( (*citor).c_str());
citor--;
nPort += atol( (*(citor)).c_str()) * 256 ;
return 0 ;
}

FILE *CFTPManager::createLocalFile(const std::string &strLocalFile)
{
return fopen(strLocalFile.c_str(), "w+b");
}

FTP_API CFTPManager::downLoad(const std::string &strRemoteFile, const std::string &strLocalFile, const int pos, const unsigned int length)
{
assert(length >= 0);

FILE *file = NULL;
unsigned long nDataLen = FTP_DEFAULT_BUFFER;
char strPos[MAX_PATH]  = {0};
int data_fd = socket(AF_INET, SOCK_STREAM, 0);

assert(data_fd != -1);

if ((length != 0) && (length < nDataLen))
{
nDataLen = length;
}
char *dataBuf = new char[nDataLen];
assert(dataBuf != NULL);

sprintf(strPos, "%d", pos);

if (createDataLink(data_fd) < 0)
{
trace("@@@@ Create Data Link error!!!\n");
return -1;
}

std::string strCmdLine = parseCommand(FTP_COMMAND_DOWNLOAD_POS, strPos);
if (Send(m_cmdSocket, strCmdLine) < 0)
{
return -1;
}
trace("@@@@Response: %s\n", serverResponse(m_cmdSocket).c_str());

strCmdLine = parseCommand(FTP_COMMAND_DOWNLOAD_FILE, strRemoteFile);

if (Send(m_cmdSocket, strCmdLine) < 0)
{
return -1;
}
trace("@@@@Response: %s\n", serverResponse(m_cmdSocket).c_str());

file = createLocalFile(std::string(FTP_DEFAULT_PATH + strLocalFile));
assert(file != NULL);

int len = 0;
int nReceiveLen = 0;
while ((len = getData(data_fd, dataBuf, nDataLen)) > 0)
{
nReceiveLen += len;

int num = fwrite(dataBuf, 1, len, file);
memset(dataBuf, 0, sizeof(dataBuf));

//trace("%s", dataBuf);
trace("Num:%d\n", num);
if (nReceiveLen == length && length != 0)
break;

if ((nReceiveLen + nDataLen) > length  && length != 0)
{
delete []dataBuf;
nDataLen = length - nReceiveLen;
dataBuf = new char[nDataLen];
}
}

Close(data_fd);
fclose(file);
delete []dataBuf;

return 0;
}

FTP_API CFTPManager::parseResponse(const std::string &str)
{
assert(!str.empty());

std::string strData = str.substr(0, 3);
unsigned int val = atoi(strData.c_str());

return val;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: