項目中新增對FTP的支持,需求的變更是開發(fā)過程中不可避免的事情,只是變更的時間越靠近項目末期,就越是災難。還好這個需求可以設計的相對獨立,做到盡量不影響已實現(xiàn)部分。
???? 說的FTP,就想起曾經(jīng)寫的一個FTP接口對象,由于現(xiàn)在FTP的實現(xiàn)庫到處都是,因此在寫好此對象時,被同事稱為:做輪子的人~我的想法是,組裝車和制作車應該還是有區(qū)別的~
???? 不扯了,下面是實現(xiàn)的代碼,比較啰嗦~
#ifndef?__FTPOPERAOBJECT_H__
#define?__FTPOPERAOBJECT_H__
#include?<fstream>
#include?<string>
#include?"ace/INET_Addr.h"
#include?"acex/NB_Tcp_Client.h"
#include?"acex/NB_Tcp_Server.h"
//OK,?support?both?PORT?and?PASV?mode?NOW.
const?int?REPLY_CODE_541????????????????=????541;
const?int?REPLY_CODE_542????????????????=????542;
const?int?REPLY_CODE_543????????????????=????543;
const?int?REPLY_CODE_544????????????????=????544;
const?int?REPLY_CODE_545????????????????=????545;
const?int?REPLY_CODE_546????????????????=????546;
const?std::string?REPLY_COMMENT_541????=????"(inner)Control?connection?is?break.";
const?std::string?REPLY_COMMENT_542????=????"(inner)Control?connection?is?timeout?for?waiting?for?remote?reply.";
const?std::string?REPLY_COMMENT_543????=????"(inner)Control?connection?gets?a?NULL?reply.";
const?std::string?REPLY_COMMENT_544????=????"(inner)Reply?result?is?empty.";
const?std::string?REPLY_COMMENT_545????=????"(inner)Syntax?error,?reply?unrecognized.";
const?std::string?REPLY_COMMENT_546????=????"(inner)Syntax?error,?reply?is?not?expected.";
class?CFTPDataTcpObject;
class?CFTPCtrlTcpObject
{
public:
????struct?ResultInfo_t
????{
????????int?m_iResult;
????????std::string?m_strInfo;
????};
????
????typedef?std::auto_ptr<CFTPDataTcpObject>?TDataTcpObjectPtr;
public:
????CFTPCtrlTcpObject(const?size_t?buf_size?=?64?*?1024,?const?ACE_Time_Value&?connect_timeout?=?ACE_Time_Value(2),?const?ACE_Time_Value&?select_timeout?=?ACE_Time_Value(2));
????virtual?~CFTPCtrlTcpObject();
public:
????int?Open(const?ACE_INET_Addr&?stAddr);
????int?Connect(const?std::string&?strUser,?const?std::string&?strPasswd);
????int?Close();
????int?CmdChgDir(const?std::string&?strDir);
????int?CmdChgLocalDir(const?std::string&?strDir);
????int?CmdMkDir(const?std::string&?strDir);
????int?CmdDelFile(const?std::string&?strFile);
????int?CmdType(bool?bASCII?=?true);
????int?CmdNoop();
????int?CmdRenFile(const?std::string&?strOldFile,?const?std::string&?strNewFile);
????int?CmdGetFile(const?std::string&?strRemoteFile,?const?std::string&?strLocalFile);
????int?CmdPutFile(const?std::string&?strLocalFile,?const?std::string&?strRemoteFile);
????int?CmdNLst(const?std::string&?strFilter,?std::string&?strOutput);
????int?CmdList(const?std::string&?strFilter,?std::string&?strOutput);
????int?SendCmdWithDataStream(const?std::string&?strCmd,?std::ostream&?os);
????int?SendCmdWithDataStream(const?std::string&?strCmd,?char*?pchData,?size_t&?szDataRead);
????
????bool?IsConnected()?const?{?return?_bConnected;?}
????bool?IsASCII()?const?{?return?_bASCII;?}
????const?ResultInfo_t&?GetResultInfo()?const;????
????size_t?AffectedSize()?const;
????void?PortMode()?{?_bPortMode?=?true;?}
????void?PasvMode()?{?_bPortMode?=?false;?}
????void?SetStopFlag(bool?bStop)?{?_bTransStop?=?bStop;?}
public:
????int?SendCommand(const?std::string&?strCmd);
????int?RecvResult(ResultInfo_t&?stResult);
????int?Is200Result(const?ResultInfo_t&?stResult)?const;
????int?Is100Result(const?ResultInfo_t&?stResult)?const;
????int?Is300Result(const?ResultInfo_t&?stResult)?const;
????int?GetLocalAddr(ACE_INET_Addr&?stAddr);
????unsigned?short?GetRandPort();
????std::string?AnalyseAddr(const?ACE_INET_Addr&?stAddr)?const;????
????ACE_INET_Addr?AnalyseAddr(const?std::string&?strAddr)?const;
public:
????int?RecvResult();
????int?ResultCode()?const;
????const?std::string&?ResultInfo()?const;
????int?Is200Result()?const;
????int?Is100Result()?const;
????int?Is300Result()?const;
protected:
????bool?_bConnected;
????ACE_RANDR_TYPE?_seed;
????char?_acResultBuf[2048];
????size_t?_szResultSize;
????bool?_bASCII;
????size_t?_szAffectedSize;//can?used?after?get?or?put?command.
????bool?_bTransStop;
????bool?_bPortMode;
private:
????size_t?_szBufSize;
????ACE_Time_Value?_stConnTimeout;
????ACE_Time_Value?_stSelectTimeout;
????std::auto_ptr<ACEX_TcpStream>?_stTcpStreamPtr;
????ACE_SOCK_Connector?_stConnector;
private:
????ResultInfo_t?_stResultInfo;
};
//
class?CFTPDataTcpObject
{
public:
????enum?TransStatus?{?TS_UNKNWON?=?-1,?TS_READ?=?0,?TS_WRITE,?TS_TIMEOUT?};
public:
????CFTPDataTcpObject(CFTPCtrlTcpObject&?ctrlobject,?size_t?buffsize,?const?ACE_Time_Value&?timeout)
????????:?_stCtrlObject(ctrlobject),?_szBuffSize(buffsize),?_stTimeout(timeout)
????????,?_stTcpStreamPtr(NULL)
????????,?_bStop(false),?_bOpen(false)
????{
????}
????virtual?~CFTPDataTcpObject();
????virtual?int?Get(const?std::string&?remote,?const?std::string&?local,?size_t&?size)?=?0;
????virtual?int?Put(const?std::string&?remote,?const?std::string&?local,?size_t&?size)?=?0;
????virtual?int?SendCmd(const?std::string&?strCmd,?std::ostream&?os)?=?0;
????virtual?int?SendCmd(const?std::string&?strCmd,?char*&?pchData,?size_t&?szDataRead)?=?0;
????void?Stop()?{?_bStop?=?true;?}
????virtual?void?Close();
protected:
????TransStatus?SelectRead(size_t&?size);
????TransStatus?SelectWrite();
????int?Read(char*&?data,?size_t&?size);
????int?Write(const?char*?data,?size_t?size);
????int?Read(std::ofstream&?ofile,?size_t&?size);
????int?Write(std::ifstream&?ifile,?size_t&?size);
????int?Read(std::ostream&?os,?size_t&?size);
protected:
????CFTPCtrlTcpObject&?_stCtrlObject;
????size_t?_szBuffSize;
????ACE_Time_Value?_stTimeout;
protected:
????ACE_INET_Addr?_stLocalAddr;
????ACE_INET_Addr?_stRemoteAddr;
????std::auto_ptr<ACEX_TcpStream>?_stTcpStreamPtr;
protected:
????bool?_bStop;
????bool?_bOpen;
};
//
class?CFTPPortDataTcpObject?:?public?CFTPDataTcpObject
{
public:
????CFTPPortDataTcpObject(CFTPCtrlTcpObject&?ctrlobject,?size_t?buffsize=?64?*?1024,?const?ACE_Time_Value&?timeout?=?ACE_Time_Value(2));
????virtual?~CFTPPortDataTcpObject();
????virtual?int?Get(const?std::string&?remote,?const?std::string&?local,?size_t&?size);
????virtual?int?Put(const?std::string&?remote,?const?std::string&?local,?size_t&?size);
????virtual?int?SendCmd(const?std::string&?strCmd,?char*&?pchData,?size_t&?szDataRead);
????virtual?int?SendCmd(const?std::string&?strCmd,?std::ostream&?os);
protected:
????int?Open();
????int?Port();
????int?Accept();
private:
????ACE_SOCK_Acceptor?_stAcceptor;
};
//
class?CFTPPasvDataTcpObject?:?public?CFTPDataTcpObject
{
public:
????CFTPPasvDataTcpObject(CFTPCtrlTcpObject&?ctrlobject,?size_t?buffsize?=?64?*?1024,?const?ACE_Time_Value&?timeout?=?ACE_Time_Value(2));
????virtual?~CFTPPasvDataTcpObject();
????virtual?int?Get(const?std::string&?remote,?const?std::string&?local,?size_t&?size);
????virtual?int?Put(const?std::string&?remote,?const?std::string&?local,?size_t&?size);
????virtual?int?SendCmd(const?std::string&?strCmd,?char*&?pchData,?size_t&?szDataRead);
????virtual?int?SendCmd(const?std::string&?strCmd,?std::ostream&?os);
protected:
????int?Pasv();
????int?Connect();
private:
????ACE_SOCK_Connector?_stConnector;
};
#endif
#include?<stdexcept>
#include?<sstream>
#include?"ace/Handle_Set.h"
#include?"ace/OS_NS_time.h"
#include?"acex/ACEX.h"
#include?"FTPOperaObject.h"
CFTPCtrlTcpObject::CFTPCtrlTcpObject(const?size_t?buf_size,?const?ACE_Time_Value&?connect_timeout,?const?ACE_Time_Value&?select_timeout)
:?_bConnected(false)
,?_seed(ACE_OS::time(NULL))
,?_szResultSize(0)
,?_bASCII(false)
,?_szAffectedSize(0)
,?_bTransStop(false)
,?_bPortMode(true)
,?_szBufSize(buf_size)
,?_stConnTimeout(connect_timeout)
,?_stSelectTimeout(select_timeout)
{
}
CFTPCtrlTcpObject::~CFTPCtrlTcpObject()
{
????Close();
}
int?CFTPCtrlTcpObject::SendCommand(const?std::string&?strCmd)
{
????if(!_stTcpStreamPtr->good())
????????return?-1;
????std::string?str?=?strCmd?+?"\r\n";
????_stTcpStreamPtr->write(str.c_str(),?str.size());
????_stTcpStreamPtr->flush();
????ACEX_LOG_OS(LM_DEBUG,?"<<CFTPCtrlTcpObject>>SendCommand()?cmd?:"?<<?str?<<?std::endl);
????return?_stTcpStreamPtr->good()???0?:?-1;
}
int?CFTPCtrlTcpObject::RecvResult(ResultInfo_t&?stResult)
{
????if(!_stTcpStreamPtr->good())
????{
????????stResult.m_iResult?=?REPLY_CODE_541;
????????stResult.m_strInfo?=?REPLY_COMMENT_541;
????????return?-1;
????}
????ACE_Handle_Set?rd_set;
????rd_set.reset();
????rd_set.set_bit(_stTcpStreamPtr->get_handle());
????int?iMaxFd?=?0;
#if?!defined(_WIN32)
????iMaxFd?=?_stTcpStreamPtr->get_handle()?+?1;
#endif
????if(ACE::select(iMaxFd,?&rd_set,?NULL,?NULL,?&_stSelectTimeout)?<=?0)
????{//timeout
????????stResult.m_iResult?=?REPLY_CODE_542;
????????stResult.m_strInfo?=?REPLY_COMMENT_542;
????????return?-1;
????}
????_stTcpStreamPtr->under_flow();
????if(!_stTcpStreamPtr->good())
????{
????????stResult.m_iResult?=?REPLY_CODE_541;
????????stResult.m_strInfo?=?REPLY_COMMENT_541;
????????return?-1;
????}
????size_t?szRead?=?_stTcpStreamPtr->in_avail();
????if(szRead?<=?0)
????{
????????stResult.m_iResult?=?REPLY_CODE_543;
????????stResult.m_strInfo?=?REPLY_COMMENT_543;
????????return?-1;
????}
????while(szRead?>?0)
????{
????????_stTcpStreamPtr->read(_acResultBuf?+?_szResultSize,?szRead);
????????_szResultSize?+=?szRead;
????????szRead?=?_stTcpStreamPtr->in_avail();
????}
????std::string?strInfo;
????strInfo.assign(_acResultBuf,?_szResultSize);
????stResult.m_strInfo?=?"";
????try
????{
????????std::string::size_type?szPos?=?strInfo.find_first_of("\r\n");
????????while(szPos?!=?std::string::npos)
????????{
????????????stResult.m_strInfo?=?strInfo.substr(0,?szPos);
????????????strInfo?=?strInfo.substr(szPos?+?2);
????????????szPos?=?strInfo.find_first_of("\r\n");
????????}
????????if(stResult.m_strInfo.empty())
????????{
????????????stResult.m_iResult?=?REPLY_CODE_544;
????????????stResult.m_strInfo?=?REPLY_COMMENT_544;
????????????return?-1;
????????}
????????szPos?=?stResult.m_strInfo.find_first_of("?");
????????if(szPos?==?std::string::npos)
????????{
????????????stResult.m_iResult?=?REPLY_CODE_545;
????????????stResult.m_strInfo?=?REPLY_COMMENT_545;
????????????return?-1;
????????}
????????stResult.m_iResult?=?atoi(stResult.m_strInfo.substr(0,?szPos).c_str());
????????stResult.m_strInfo?=?stResult.m_strInfo.substr(szPos?+?1);
????}
????catch(std::out_of_range&?e)
????{
????????ACEX_LOG_OS(LM_WARNING,?"<<CFTPCtrlTcpObject>>RecvResult()?exception(out_of_range)?-?remote?maybe?not?FTP?server."?<<?std::endl);
????????stResult.m_iResult?=?REPLY_CODE_546;
????????stResult.m_strInfo?=?REPLY_COMMENT_546;
????????return?-1;
????}
????_szResultSize?=?0;
????return?0;
}
int?CFTPCtrlTcpObject::RecvResult()
{
????if(RecvResult(_stResultInfo)?==?0)
????{
????????ACEX_LOG_OS(LM_DEBUG,?"<<CFTPCtrlTcpObject>>RecvResult()?Result("?<<?_stResultInfo.m_iResult?<<?")"?<<?_stResultInfo.m_strInfo?<<?std::endl);
????????return?0;
????}
????else
????{
????????ACEX_LOG_OS(LM_WARNING,?"<<CFTPCtrlTcpObject>>RecvResult()?Result("?<<?_stResultInfo.m_iResult?<<?")"?<<?_stResultInfo.m_strInfo?<<?std::endl);
????????return?-1;
????}
}
int?CFTPCtrlTcpObject::ResultCode()?const
{
????return?_stResultInfo.m_iResult;
}
const?std::string&?CFTPCtrlTcpObject::ResultInfo()?const
{
????return?_stResultInfo.m_strInfo;
}
int?CFTPCtrlTcpObject::Open(const?ACE_INET_Addr&?stAddr)
{
????_stTcpStreamPtr.reset(new?ACEX_TcpStream(_szBufSize));
????ACE_Time_Value?st(5,0);
????if(_stConnector.connect(*_stTcpStreamPtr.get(),?stAddr,?&st)?==?0)
????{
????????_stTcpStreamPtr->block(0);
????????RecvResult();
????????if(Is200Result()?==?0)
????????{
????????????_bConnected?=?true;
????????????return?0;
????????}
????????else
????????{
????????????Close();
????????}
????}
????return?-1;
}
int?CFTPCtrlTcpObject::Connect(const?std::string&?strUser,?const?std::string&?strPasswd)
{
????//if(_bConnected)
????//{
????//????SendCommand("USER?"?+?strUser);
????//????RecvResult();
????//????if(_stResultInfo.m_iResult?==?331)
????//????{
????//????????SendCommand("PASS?"?+?strPasswd);
????//????????RecvResult();
????//????????if(Is200Result()?==?0)
????//????????{//set?default?trans?mode
????//????????????return?CmdType(_bASCII);
????//????????}
????//????}
????//}
????//return?-1;
????if(_bConnected)
????{
????????SendCommand("USER?"?+?strUser);
????????while(RecvResult()?==?0)
????????{
????????????if(_stResultInfo.m_iResult?==?331)
????????????{
????????????????SendCommand("PASS?"?+?strPasswd);
????????????????RecvResult();
????????????????if(Is200Result()?==?0)
????????????????{//set?default?trans?mode
????????????????????return?CmdType(_bASCII);
????????????????}
????????????}
????????}
????}
????return?-1;
}
int?CFTPCtrlTcpObject::Close()
{
????if(_bConnected)
????{
????????SendCommand("QUIT");
????????RecvResult();
????????_stTcpStreamPtr->close();
????????_bConnected?=?false;
????}
????return?0;
}
const?CFTPCtrlTcpObject::ResultInfo_t&?CFTPCtrlTcpObject::GetResultInfo()?const
{
????return?_stResultInfo;
}
int?CFTPCtrlTcpObject::Is200Result(const?ResultInfo_t&?stResult)?const
{
????if(stResult.m_iResult?>=200?&&?stResult.m_iResult?<?300)
????????return?0;
????else
????????return?-1;
}
int?CFTPCtrlTcpObject::Is100Result(const?ResultInfo_t&?stResult)?const
{
????if(stResult.m_iResult?>=100?&&?stResult.m_iResult?<?200)
????????return?0;
????else
????????return?-1;
}
int?CFTPCtrlTcpObject::Is300Result(const?ResultInfo_t&?stResult)?const
{
????if(stResult.m_iResult?>=300?&&?stResult.m_iResult?<?400)
????????return?0;
????else
????????return?-1;
}
int?CFTPCtrlTcpObject::Is200Result()?const
{
????return?Is200Result(_stResultInfo);
}
int?CFTPCtrlTcpObject::Is100Result()?const
{
????return?Is100Result(_stResultInfo);
}
int?CFTPCtrlTcpObject::Is300Result()?const
{
????return?Is300Result(_stResultInfo);
}
//////////////////////////////////////////////////////////////////////////
int?CFTPCtrlTcpObject::CmdChgDir(const?std::string&?strDir)
{
????SendCommand("CWD?"?+?strDir);
????RecvResult();
????return?Is200Result();
}
int?CFTPCtrlTcpObject::CmdChgLocalDir(const?std::string&?strDir)
{
????return?ACE_OS::chdir(strDir.c_str());
}
int?CFTPCtrlTcpObject::CmdMkDir(const?std::string&?strDir)
{
????SendCommand("MKD?"?+?strDir);
????RecvResult();
????return?Is200Result();
}
int?CFTPCtrlTcpObject::CmdDelFile(const?std::string&?strFile)
{
????SendCommand("DELE?"?+?strFile);
????RecvResult();
????return?Is200Result();
}
int?CFTPCtrlTcpObject::CmdType(bool?bASCII?/*?=?true?*/)
{
????_bASCII?=?bASCII;
????if(bASCII)
????{
????????SendCommand("TYPE?A");
????}
????else
????{
????????SendCommand("TYPE?I");
????}
????RecvResult();
????return?Is200Result();
}
int?CFTPCtrlTcpObject::CmdNoop()
{
????SendCommand("NOOP");
????RecvResult();
????return?Is200Result();
}
int?CFTPCtrlTcpObject::CmdRenFile(const?std::string&?strOldFile,?const?std::string&?strNewFile)
{
????SendCommand("RNFR?"?+?strOldFile);
????RecvResult();
????if(_stResultInfo.m_iResult?==?350)
????{
????????SendCommand("RNTO?"?+?strNewFile);
????????RecvResult();
????????return?Is200Result();
????}
????else
????{
????????return??-1;
????}
}
int?CFTPCtrlTcpObject::CmdGetFile(const?std::string&?strRemoteFile,?const?std::string&?strLocalFile)
{
????_szAffectedSize?=?0;
????TDataTcpObjectPtr?ptr(NULL);
????if(_bPortMode)
????????ptr.reset(new?CFTPPortDataTcpObject(*this));
????else
????????ptr.reset(new?CFTPPasvDataTcpObject(*this));
????if(ptr->Get(strRemoteFile,?strLocalFile,?_szAffectedSize)?!=?0)
????????return?-1;
????ptr->Close();
????RecvResult();
????return?Is200Result();
}
int?CFTPCtrlTcpObject::CmdPutFile(const?std::string&?strLocalFile,?const?std::string&?strRemoteFile)
{
????_szAffectedSize?=?0;
????TDataTcpObjectPtr?ptr(NULL);
????if(_bPortMode)
????????ptr.reset(new?CFTPPortDataTcpObject(*this));
????else
????????ptr.reset(new?CFTPPasvDataTcpObject(*this));
????if(ptr->Put(strRemoteFile,?strLocalFile,?_szAffectedSize)?!=?0)
????????return?-1;
????ptr->Close();
????RecvResult();
????return?Is200Result();????
}
int?CFTPCtrlTcpObject::CmdNLst(const?std::string&?strFilter,?std::string&?strOutput)
{
????std::string?strCmd?=?"NLST";
????if(!strFilter.empty())
????????strCmd?+=?"?"?+?strFilter;
????std::ostringstream?ostr;
????if(SendCmdWithDataStream(strCmd,?ostr)?!=?0)
????????return?-1;
????strOutput?=?ostr.str();
????return?0;
}
int?CFTPCtrlTcpObject::CmdList(const?std::string&?strFilter,?std::string&?strOutput)
{
????std::string?strCmd?=?"LIST";
????if(!strFilter.empty())
????????strCmd?+=?"?"?+?strFilter;
????std::ostringstream?ostr;
????if(SendCmdWithDataStream(strCmd,?ostr)?!=?0)
????????return?-1;
????strOutput?=?ostr.str();
????return?0;
}
int?CFTPCtrlTcpObject::SendCmdWithDataStream(const?std::string&?strCmd,?std::ostream&?os)
{
????TDataTcpObjectPtr?ptr(NULL);
????if(_bPortMode)
????????ptr.reset(new?CFTPPortDataTcpObject(*this));
????else
????????ptr.reset(new?CFTPPasvDataTcpObject(*this));
????if(ptr->SendCmd(strCmd,?os)?!=?0)
????????return?-1;
????ptr->Close();
????RecvResult();
????return?Is200Result();????
}
int?CFTPCtrlTcpObject::SendCmdWithDataStream(const?std::string&?strCmd,?char*?pchData,?size_t&?szDataRead)
{
????TDataTcpObjectPtr?ptr(NULL);
????if(_bPortMode)
????????ptr.reset(new?CFTPPortDataTcpObject(*this));
????else
????????ptr.reset(new?CFTPPasvDataTcpObject(*this));
????if(ptr->SendCmd(strCmd,?pchData,?szDataRead)?!=?0)
????????return?-1;
????ptr->Close();
????RecvResult();
????return?Is200Result();????
}
size_t?CFTPCtrlTcpObject::AffectedSize()?const
{
????return?_szAffectedSize;
}
int?CFTPCtrlTcpObject::GetLocalAddr(ACE_INET_Addr&?stAddr)
{
????if(!_bConnected)
????????return?-1;
????_stTcpStreamPtr->get_local_addr(stAddr);
????return?0;
}
unsigned?short?CFTPCtrlTcpObject::GetRandPort()
{
????int?iRand?=?ACE_OS::rand_r(_seed);
????while(iRand?<?20000)
????{
????????iRand?=?ACE_OS::rand_r(_seed);
????}
????return?iRand;
}
std::string?CFTPCtrlTcpObject::AnalyseAddr(const?ACE_INET_Addr&?stAddr)?const
{
????std::ostringstream?ostr;
????ostr?<<?stAddr.get_host_addr();
????ostr?<<?","?<<?stAddr.get_port_number()?/?256?<<?","?<<?stAddr.get_port_number()?%?256;
????std::string?str?=?ostr.str();
????std::string::size_type?st?=?str.find_first_of(".");
????while(st?!=?std::string::npos)
????{
????????str?=?str.replace(st,?1,?",");
????????st?=?str.find_first_of(".");
????}
????return?str;
}
ACE_INET_Addr?CFTPCtrlTcpObject::AnalyseAddr(const?std::string&?strAddr)?const
{
????std::string?str?=?strAddr;
????std::ostringstream?ostr;
????std::string::size_type?pos?=?str.find(',');
????if(pos?!=?std::string::npos)
????????ostr?<<?str.substr(0,?pos)?<<?".";
????else
????????return?ACE_INET_Addr("0.0.0.0:0");
????str?=?str.substr(pos?+?1);
????pos?=?str.find(',');
????if(pos?!=?std::string::npos)
????????ostr?<<?str.substr(0,?pos)?<<?".";
????else
????????return?ACE_INET_Addr("0.0.0.0:0");
????str?=?str.substr(pos?+?1);
????pos?=?str.find(',');
????if(pos?!=?std::string::npos)
????????ostr?<<?str.substr(0,?pos)?<<?".";
????else
????????return?ACE_INET_Addr("0.0.0.0:0");
????str?=?str.substr(pos?+?1);
????pos?=?str.find(',');
????if(pos?!=?std::string::npos)
????????ostr?<<?str.substr(0,?pos)?<<?":";
????else
????????return?ACE_INET_Addr("0.0.0.0:0");
????str?=?str.substr(pos?+?1);
????pos?=?str.find(',');
????if(pos?!=?std::string::npos)
????????ostr?<<?atoi(str.substr(0,?pos).c_str())?*?256?+?atoi(str.substr(pos?+?1).c_str());
????return?ACE_INET_Addr(ostr.str().c_str());
}
//////////////////////////////////////////////////////////////////////////
CFTPDataTcpObject::~CFTPDataTcpObject()
{
????Close();
}
CFTPDataTcpObject::TransStatus?CFTPDataTcpObject::SelectRead(size_t?&size)
{
????if(!_stTcpStreamPtr->good())
????????return?TS_UNKNWON;
????ACE_Handle_Set?rd_set;
????rd_set.reset();
????rd_set.set_bit(_stTcpStreamPtr->get_handle());
????int?iMaxFd?=?0;
#if?!defined(_WIN32)
????iMaxFd?=?_stTcpStreamPtr->get_handle()?+?1;
#endif
????if(ACE::select(iMaxFd,?&rd_set,?NULL,?NULL,?&_stTimeout)?<=?0)
????{
????????return?TS_TIMEOUT;
????}
????_stTcpStreamPtr->under_flow();
????size?=?_stTcpStreamPtr->in_avail();
????return?TS_READ;
}
CFTPDataTcpObject::TransStatus?CFTPDataTcpObject::SelectWrite()
{
????if(!_stTcpStreamPtr->good())
????????return?TS_UNKNWON;
????ACE_Handle_Set?wr_set;
????wr_set.reset();
????wr_set.set_bit(_stTcpStreamPtr->get_handle());
????int?iMaxFd?=?0;
#if?!defined(_WIN32)
????iMaxFd?=?_stTcpStreamPtr->get_handle()?+?1;
#endif
????if(ACE::select(iMaxFd,?NULL,?&wr_set,?NULL,?&_stTimeout)?<=?0)
????{
????????return?TS_TIMEOUT;
????}
????return?TS_WRITE;
}
int?CFTPDataTcpObject::Read(char*&?data,?size_t&?size)
{
????size?=?0;
????data?=?NULL;
????while(_stTcpStreamPtr->good())
????{
????????if(_bStop)
????????????return?-1;
????????size_t?szRead?=?0;
????????TransStatus?eTrans?=?SelectRead(szRead);
????????if(eTrans?==?TS_READ)
????????{
????????????if(szRead?==?0)
????????????????break;
????????????char*?pch?=?new?char[szRead];
????????????if(_stTcpStreamPtr->read(pch,?szRead).good())
????????????{
????????????????if(data?!=?NULL)
????????????????{
????????????????????delete?[]?data;
????????????????????data?=?new?char[size?+?szRead];
????????????????}
????????????????memcpy(data?+?size,?pch,?szRead);
????????????????size?+=?szRead;
????????????}
????????????else
????????????{
????????????????delete?[]?pch;
????????????????return?-1;
????????????}
????????????delete?[]?pch;
????????}
????????else?if(eTrans?==?CFTPDataTcpObject::TS_TIMEOUT)
????????{
????????????continue;
????????}
????????else
????????{
????????????return?-1;
????????}
????}
????return?0;
}
int?CFTPDataTcpObject::Write(const?char*?data,?size_t?size)
{
????size_t?szWrite?=?0;
????while(szWrite?<?size)
????{
????????if(_bStop)
????????????return?-1;
????????TransStatus?eTrans?=?SelectWrite();
????????if(eTrans?==?CFTPDataTcpObject::TS_WRITE)
????????{
????????????if(size?-?szWrite?>=?5120)
????????????{
????????????????_stTcpStreamPtr->write(data?+?szWrite,?5120);
????????????????if(!_stTcpStreamPtr->flush().good())
????????????????????return?-1;
????????????}
????????????else
????????????{
????????????????_stTcpStreamPtr->write(data?+?szWrite,?size?-?szWrite);
????????????????if(!_stTcpStreamPtr->flush().good())
????????????????????return?-1;
????????????}
????????????szWrite?+=?5120;
????????}
????????else?if(eTrans?==?CFTPDataTcpObject::TS_TIMEOUT)
????????{
????????????continue;
????????}
????????else
????????{
????????????break;
????????}
????}
????return?0;
}
int?CFTPDataTcpObject::Read(std::ofstream?&ofile,?size_t&?size)
{
????if(!ofile.good())
????????return?-1;
????size?=?0;
????while(_stTcpStreamPtr->good())
????{
????????if(_bStop)
????????????return?-1;
????????size_t?szRead?=?0;
????????TransStatus?eTrans?=?SelectRead(szRead);
????????if(eTrans?==?TS_READ)
????????{
????????????if(szRead?==?0)
????????????????break;
????????????char*?pch?=?new?char[szRead];
????????????if(_stTcpStreamPtr->read(pch,?szRead).good())
????????????{
????????????????ofile.write(pch,?szRead);
????????????????size?+=?szRead;
????????????????if(!ofile.good())
????????????????{
????????????????????delete?[]?pch;
????????????????????return?-1;
????????????????}
????????????}
????????????else
????????????{
????????????????delete?[]?pch;
????????????????return?-1;
????????????}
????????????delete?[]?pch;
????????}
????????else?if(eTrans?==?CFTPDataTcpObject::TS_TIMEOUT)
????????{
????????????continue;
????????}
????????else
????????{
????????????return?-1;
????????}
????}
????return?0;
}
int?CFTPDataTcpObject::Write(std::ifstream?&ifile,?size_t?&size)
{
????if(!ifile.good())
????????return?-1;
????size?=?0;
????char?buf[5120];
????while(!ifile.eof()?&&?ifile.good())
????{
????????if(_bStop)
????????????return?-1;
????????TransStatus?eTrans?=?SelectWrite();
????????if(eTrans?==?CFTPDataTcpObject::TS_WRITE)
????????{????
????????????size_t?szRead?=?ifile.read(buf,?5120).gcount();
????????????if(szRead?>?0)
????????????{
????????????????_stTcpStreamPtr->write(buf,?szRead);
????????????????if(!_stTcpStreamPtr->flush().good())
????????????????????return?-1;
????????????????size?+=?szRead;
????????????}
????????????else
????????????{
????????????????break;
????????????}
????????}
????????else?if(eTrans?==?CFTPDataTcpObject::TS_TIMEOUT)
????????{
????????????continue;
????????}
????????else
????????{
????????????break;
????????}
????}
????return?0;
}
int?CFTPDataTcpObject::Read(std::ostream?&os,?size_t&?size)
{
????if(!os.good())
????????return?-1;
????size?=?0;
????while(_stTcpStreamPtr->good())
????{
????????if(_bStop)
????????????return?-1;
????????size_t?szRead?=?0;
????????TransStatus?eTrans?=?SelectRead(szRead);
????????if(eTrans?==?TS_READ)
????????{
????????????if(szRead?==?0)
????????????????break;
????????????char*?pch?=?new?char[szRead];
????????????if(_stTcpStreamPtr->read(pch,?szRead).good())
????????????{
????????????????os.write(pch,?szRead);
????????????????size?+=?szRead;
????????????????if(!os.good())
????????????????{
????????????????????delete?[]?pch;
????????????????????return?-1;
????????????????}
????????????}
????????????else
????????????{
????????????????delete?[]?pch;
????????????????return?-1;
????????????}
????????????delete?[]?pch;
????????}
????????else?if(eTrans?==?CFTPDataTcpObject::TS_TIMEOUT)
????????{
????????????continue;
????????}
????????else
????????{
????????????return?-1;
????????}
????}
????return?0;
}
void?CFTPDataTcpObject::Close()
{
????if(_stTcpStreamPtr.get()?!=?NULL)
????{
????????_stTcpStreamPtr->close();
????????_stTcpStreamPtr.reset(NULL);
????}????
}
////
CFTPPortDataTcpObject::CFTPPortDataTcpObject(CFTPCtrlTcpObject?&ctrlobject,?size_t?buffsize,?const?ACE_Time_Value?&timeout)
:?CFTPDataTcpObject(ctrlobject,?buffsize,?timeout)
{
}
CFTPPortDataTcpObject::~CFTPPortDataTcpObject()
{
}
int?CFTPPortDataTcpObject::Get(const?std::string?&remote,?const?std::string?&local,?size_t&?size)
{
????if(!_stCtrlObject.IsConnected())
????????return?-1;
????std::ios_base::openmode?mode?=?std::ios::trunc?|?std::ios::out;
????if(!_stCtrlObject.IsASCII())
????????mode?|=?std::ios_base::binary;
????std::ofstream?ofile(local.c_str(),?mode);
????if(!ofile.is_open()?||?!ofile.good())
????????return?-1;
????if(Open()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::Get>open()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Port()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::Get>port()?failed."?<<?std::endl);
????????return?-1;
????}
//????CFTPCtrlTcpObject::ResultInfo_t?result;
????_stCtrlObject.SendCommand("RETR?"?+?remote);
????_stCtrlObject.RecvResult();
????if(_stCtrlObject.Is100Result()?!=?0)
//????if(result.m_iResult?<?100?||?result.m_iResult?>?199)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::Get>RETR?command?failed."?<<?std::endl);
????????return?-1;
????}
????if(Accept()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::Get>accept()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Read(ofile,?size)?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::Get>Read()?failed."?<<?std::endl);
????????return?-1;
????}
????ofile.close();
????return?0;
}
int?CFTPPortDataTcpObject::Put(const?std::string&?remote,?const?std::string&?local,?size_t&?size)
{
????if(!_stCtrlObject.IsConnected())
????????return?-1;
????std::ios_base::openmode?mode?=?std::ios_base::in;
????if(!_stCtrlObject.IsASCII())
????????mode?|=?std::ios_base::binary;
????std::ifstream?ifile(local.c_str(),?mode);
????if(!ifile.is_open()?||?!ifile.good())
????????return?-1;
????if(Open()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::Put>open()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Port()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::Put>port()?failed."?<<?std::endl);
????????return?-1;
????}
//????CFTPCtrlTcpObject::ResultInfo_t?result;
????_stCtrlObject.SendCommand("STOR?"?+?remote);
????_stCtrlObject.RecvResult();
//????if(result.m_iResult?<?100?||?result.m_iResult?>?199)
????if(_stCtrlObject.Is100Result()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::Put>STOR?command?failed."?<<?std::endl);
????????return?-1;
????}
????if(Accept()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::Put>accept()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Write(ifile,?size)?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::Put>Write()?failed."?<<?std::endl);
????????return?-1;
????}
????ifile.close();
????return?0;
}
int?CFTPPortDataTcpObject::SendCmd(const?std::string&?strCmd,?char*&?pchData,?size_t&?szDataRead)
{
????if(!_stCtrlObject.IsConnected())
????????return?-1;
????if(Open()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::SendCmd>open()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Port()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::SendCmd>port()?failed."?<<?std::endl);
????????return?-1;
????}
//????CFTPCtrlTcpObject::ResultInfo_t?result;
????_stCtrlObject.SendCommand(strCmd);
????_stCtrlObject.RecvResult();
//????if(result.m_iResult?<?100?||?result.m_iResult?>?199)
????if(_stCtrlObject.Is100Result()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::SendCmd>"?<<?strCmd?<<?"?command?failed."?<<?std::endl);
????????return?-1;
????}
????if(Accept()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::SendCmd>accept()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Read(pchData,?szDataRead)?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::SendCmd>Read()?failed."?<<?std::endl);
????????return?-1;
????}
????return?0;
}
int?CFTPPortDataTcpObject::SendCmd(const?std::string&?strCmd,?std::ostream&?os)
{
????if(!_stCtrlObject.IsConnected())
????????return?-1;
????if(Open()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::SendCmd>open()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Port()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::SendCmd>port()?failed."?<<?std::endl);
????????return?-1;
????}
//????CFTPCtrlTcpObject::ResultInfo_t?result;
????_stCtrlObject.SendCommand(strCmd);
????_stCtrlObject.RecvResult();
????//if(result.m_iResult?<?100?||?result.m_iResult?>?199)
????if(_stCtrlObject.Is100Result()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::SendCmd>"?<<?strCmd?<<?"?command?failed."?<<?std::endl);
????????return?-1;
????}
????if(Accept()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::SendCmd>accept()?failed."?<<?std::endl);
????????return?-1;
????}
????size_t?szDataRead?=?0;
????if(Read(os,?szDataRead)?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPortDataTcpObject::SendCmd>Read()?failed."?<<?std::endl);
????????return?-1;
????}
????return?0;
}
int?CFTPPortDataTcpObject::Open()
{
????_stCtrlObject.GetLocalAddr(_stLocalAddr);
????_stLocalAddr.set_port_number(_stCtrlObject.GetRandPort());
????while(_stAcceptor.open(_stLocalAddr)?!=?0)
????{
????????_stLocalAddr.set_port_number(_stCtrlObject.GetRandPort());
????}
????_bOpen?=?true;
????return?0;
}
int?CFTPPortDataTcpObject::Port()
{
//????CFTPCtrlTcpObject::ResultInfo_t?result;
????std::string?strPort?=?_stCtrlObject.AnalyseAddr(_stLocalAddr);
????_stCtrlObject.SendCommand("PORT?"?+?strPort);
????_stCtrlObject.RecvResult();
????if(_stCtrlObject.Is200Result()?!=?0)
????????return?-1;
????return?0;????
}
int?CFTPPortDataTcpObject::Accept()
{
????ACE_Handle_Set?rd_set;
????rd_set.reset();
????rd_set.set_bit(_stAcceptor.get_handle());
????int?iMaxFd?=?0;
#if?!defined(_WIN32)
????iMaxFd?=?_stAcceptor.get_handle()?+?1;
#endif
????if(ACE::select(iMaxFd,?&rd_set,?NULL,?NULL,?&_stTimeout)?>?0)
????{
????????if(rd_set.is_set(_stAcceptor.get_handle()))
????????{
????????????_stTcpStreamPtr.reset(new?ACEX_TcpStream(_szBuffSize));
????????????if(_stAcceptor.accept(*_stTcpStreamPtr.get())?==?0)
????????????{
????????????????_stTcpStreamPtr->block(0);
????????????}
????????????else
????????????{
????????????????_stTcpStreamPtr.reset(NULL);
????????????}
????????}
????}
????_stAcceptor.close();
????if(_stTcpStreamPtr.get()?!=?NULL)
????????return?0;
????_bOpen?=?false;
????return?-1;
}
//
CFTPPasvDataTcpObject::CFTPPasvDataTcpObject(CFTPCtrlTcpObject&?ctrlobject,?size_t?buffsize?/*?=?64?*?1024?*/,?const?ACE_Time_Value&?timeout?/*?=?ACE_Time_Value?*/)
:?CFTPDataTcpObject(ctrlobject,?buffsize,?timeout)
{
}
CFTPPasvDataTcpObject::~CFTPPasvDataTcpObject()
{
}
int?CFTPPasvDataTcpObject::Get(const?std::string?&remote,?const?std::string?&local,?size_t?&size)
{
????if(!_stCtrlObject.IsConnected())
????????return?-1;
????std::ios_base::openmode?mode?=?std::ios::trunc?|?std::ios::out;
????if(!_stCtrlObject.IsASCII())
????????mode?|=?std::ios_base::binary;
????std::ofstream?ofile(local.c_str(),?mode);
????if(!ofile.is_open()?||?!ofile.good())
????????return?-1;
????if(Pasv()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::Get>Pasv()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Connect()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::Get>Connect()?failed."?<<?std::endl);
????????return?-1;
????}
//????CFTPCtrlTcpObject::ResultInfo_t?result;
????_stCtrlObject.SendCommand("RETR?"?+?remote);
????_stCtrlObject.RecvResult();
//????if(result.m_iResult?<?100?||?result.m_iResult?>?199)
????if(_stCtrlObject.Is100Result()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::Get>RETR?command?failed."?<<?std::endl);
????????return?-1;
????}
????if(Read(ofile,?size)?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::Get>Read()?failed."?<<?std::endl);
????????return?-1;
????}
????ofile.close();
????return?0;
}
int?CFTPPasvDataTcpObject::Put(const?std::string&?remote,?const?std::string&?local,?size_t&?size)
{
????if(!_stCtrlObject.IsConnected())
????????return?-1;
????std::ios_base::openmode?mode?=?std::ios_base::in;
????if(!_stCtrlObject.IsASCII())
????????mode?|=?std::ios_base::binary;
????std::ifstream?ifile(local.c_str(),?mode);
????if(!ifile.is_open()?||?!ifile.good())
????????return?-1;
????if(Pasv()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::Put>Pasv()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Connect()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::Put>Connect()?failed."?<<?std::endl);
????????return?-1;
????}
//????CFTPCtrlTcpObject::ResultInfo_t?result;
????_stCtrlObject.SendCommand("STOR?"?+?remote);
????_stCtrlObject.RecvResult();
//????if(result.m_iResult?<?100?||?result.m_iResult?>?199)
????if(_stCtrlObject.Is100Result()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::Put>STOR?command?failed."?<<?std::endl);
????????return?-1;
????}
????if(Write(ifile,?size)?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::Put>Write()?failed."?<<?std::endl);
????????return?-1;
????}
????ifile.close();
????return?0;
}
int?CFTPPasvDataTcpObject::SendCmd(const?std::string&?strCmd,?char*&?pchData,?size_t&?szDataRead)
{
????if(!_stCtrlObject.IsConnected())
????????return?-1;
????if(Pasv()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::SendCmd>Pasv()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Connect()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::SendCmd>Connect()?failed."?<<?std::endl);
????????return?-1;
????}
//????CFTPCtrlTcpObject::ResultInfo_t?result;
????_stCtrlObject.SendCommand(strCmd);
????_stCtrlObject.RecvResult();
//????if(result.m_iResult?<?100?||?result.m_iResult?>?199)
????if(_stCtrlObject.Is100Result()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::SendCmd>"?<<?strCmd?<<?"?command?failed."?<<?std::endl);
????????return?-1;
????}
????if(Read(pchData,?szDataRead)?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::SendCmd>Read()?failed."?<<?std::endl);
????????return?-1;
????}
????return?0;
}
int?CFTPPasvDataTcpObject::SendCmd(const?std::string&?strCmd,?std::ostream&?os)
{
????if(!_stCtrlObject.IsConnected())
????????return?-1;
????if(Pasv()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::SendCmd>Pasv()?failed."?<<?std::endl);
????????return?-1;
????}
????if(Connect()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::SendCmd>Connect()?failed."?<<?std::endl);
????????return?-1;
????}
//????CFTPCtrlTcpObject::ResultInfo_t?result;
????_stCtrlObject.SendCommand(strCmd);
????_stCtrlObject.RecvResult();
//????if(result.m_iResult?<?100?||?result.m_iResult?>?199)
????if(_stCtrlObject.Is100Result()?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::SendCmd>"?<<?strCmd?<<?"?command?failed."?<<?std::endl);
????????return?-1;
????}
????size_t?szDataRead?=?0;
????if(Read(os,?szDataRead)?!=?0)
????{
????????ACEX_LOG_OS(LM_ERROR,?"<CFTPPasvDataTcpObject::SendCmd>Read()?failed."?<<?std::endl);
????????return?-1;
????}
????return?0;
}
int?CFTPPasvDataTcpObject::Pasv()
{
//????CFTPCtrlTcpObject::ResultInfo_t?result;
????_stCtrlObject.SendCommand("PASV");
????_stCtrlObject.RecvResult();
????if(_stCtrlObject.ResultCode()?!=?227)
????{
????????return?-1;
????}
????std::string?info?=?_stCtrlObject.ResultInfo();
????std::string?str?=?"";
//????unsigned?short?port?=?0;?
//????size_t?pos?=?0;
????for(std::string::const_iterator?it?=?info.begin();?it?!=?info.end();?++?it)
????{
????????if((*it?>=?'0'?&&?*it?<=?'9')?||?(*it?==?','))
????????{
????????????str?+=?*it;
????????}
????}
????_stRemoteAddr?=?_stCtrlObject.AnalyseAddr(str);
????return?0;????
}
int?CFTPPasvDataTcpObject::Connect()
{
????_stTcpStreamPtr.reset(new?ACEX_TcpStream(_szBuffSize));
????if(_stConnector.connect(*_stTcpStreamPtr.get(),?_stRemoteAddr,?&_stTimeout)?==?0)
????{
????????_stTcpStreamPtr->block(0);
????}
????else
????{
????????_stTcpStreamPtr.reset(NULL);
????}
????if(_stTcpStreamPtr.get()?!=?NULL)
????????return?0;
????_bOpen?=?false;
????return?-1;
}