青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Codejie's C++ Space

Using C++

輪子:FTP接口實現

項目中新增對FTP的支持,需求的變更是開發過程中不可避免的事情,只是變更的時間越靠近項目末期,就越是災難。還好這個需求可以設計的相對獨立,做到盡量不影響已實現部分。
???? 說的FTP,就想起曾經寫的一個FTP接口對象,由于現在FTP的實現庫到處都是,因此在寫好此對象時,被同事稱為:做輪子的人~我的想法是,組裝車和制作車應該還是有區別的~
???? 不扯了,下面是實現的代碼,比較啰嗦~

#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;
}


posted on 2009-07-31 10:22 codejie 閱讀(1337) 評論(14)  編輯 收藏 引用 所屬分類: C++

評論

# re: 輪子:FTP接口實現 2009-08-06 14:27 uwinb

我也做過這樣的輪子,不過我在實現FTP客戶端之前先干了一件事,就是按照流對象的概念封裝了套接口,讓它自己智能地維護緩沖區!在單線程環境下,客戶端也能實現以PORT方式登錄Unix的FTP服務端。還有遇到一個問題,就是調用一次recv()不一定就能收全數據,可能需要反復測試可讀性和調用接收函數,這也是封裝套接口的原因之一。  回復  更多評論   

# re: 輪子:FTP接口實現 2009-08-06 17:28 codejie

我是按照FTP的思想封裝的,分Contral和Data兩個對象,然后再分Pasv和Port兩個Data子對象。
你說到的流對象封裝,我是在Data中作的~
嘿嘿,咱們做輪子的想法都一樣~  回復  更多評論   

# re: 輪子:FTP接口實現 2009-08-08 19:19 uwinb

FTP其實就是個有問有答的協商協議,Pasv和Port只不過是兩種登錄的方式,在我的方案中發現其中一種失效會自動去嘗試另一種,不管咋的建立聯接以后的數據傳遞沒啥子區別。所以對你的類框架模型稍有質疑,呵呵!
還有涉及訪問網絡這種充滿不可預測的事件的對象,你居然不使用異常來反饋錯誤!學術討論而已,不必介意我的觀點。  回復  更多評論   

# re: 輪子:FTP接口實現 2009-08-09 20:16 codejie

先說異常的問題,你說的很對,在第一版本時,實現中都是異常方式,由于外層調用的代碼不是我寫的,并且不喜歡異常,我被迫改成0和-1方式了,因此也增加了很多自定義的錯誤碼~實話說,我還是喜歡異常方式的,嘿嘿~
關于PASV和PORT方式,我認為不是你說的‘登錄’方式,而應該是數據傳輸的兩種連接模式,當然如果你說的‘登錄’就是指這個連接,那么我們就一樣了~我說明一下吧,PASV模式是指在數據傳輸時,服務器端做Server;而PORT模式相反。具體可以參看FTP協議。
我不知道你方案中的“發現其中一種失效會自動去嘗試另一種”是何種需求下實現的,我這里只是對兩種模式的對象封裝,至于如何使用這些對象,是上層調用去決定的。像某些FTP服務端為了防止‘請求’方式攻擊,而僅支持PORT方式。所以這里的對象自身無需去考慮“失效”和“嘗試”的問題。

我很介意你的觀點,因為我認為--不同的思想只有去碰撞,才能共同改善~  回復  更多評論   

# re: 輪子:FTP接口實現 2009-09-08 19:57 白云深

謝謝樓主的代碼。

另外有個問題請教一下:“ACEX_TcpStream”這個對象是什么庫里面的,還是樓主自己封裝的?  回復  更多評論   

# re: 輪子:FTP接口實現 2009-09-08 22:38 codejie

客氣了~
ACEX_TcpStream類是對Socket的封裝,出自工作中使用的ACEX庫,這個不是我封的,從功能看應該基于Socket和Stream兩個基類。把這個類看成Socket流對象就可以了,這個不是重點了。  回復  更多評論   

# re: 輪子:FTP接口實現 2009-09-08 23:31 白云深

多謝樓主答復。

本人是個菜鳥,所以細節上有好多問題不明白。  回復  更多評論   

# re: 輪子:FTP接口實現 2009-09-09 21:32 codejie

客氣了~有問題,咱一起想~  回復  更多評論   

# re: 輪子:FTP接口實現 2009-09-09 21:46 白云深

呵呵,謝謝樓主的熱心。

雖然不恥下問是個好習慣,但基礎的東西還是要靠自己的學習,自己不學習隨意張口問別人也不是學習的好態度,同時也是浪費別人的時間和自己的智商。不說了,學習了,呵呵。以后會經常來博主這,向博主請益,博主可要勤奮點哦,博主多寫文章就是對俺們菜鳥最大的幫助。  回復  更多評論   

# re: 輪子:FTP接口實現 2009-09-09 22:35 codejie

求你多來問吧,么發現近來代碼越來越少了嗎?這里都成了我發牢騷的地方了。你的問題也是讓我前進的動力~  回復  更多評論   

# re: 輪子:FTP接口實現 2009-09-10 21:39 白云深

今天把博主的代碼整理了一下,暫時調試了一下port模式。把下面這個函數

int CFTPDataTcpObject::Read(char*& data, size_t& size)

改為:

int CFTPDataTcpObject::Read(std::string & data)

博主的實現中,用new來動態分配內存,但好像沒有釋放,按博主的實現,這個釋放動作應該要由上層調用來完成,不知道我的理解是否正確。如果所說無誤,這是否可以理解為這個接口會造成泄漏或與上層程序有耦合?

另外,如果不用std::string來返回數據以防止內存泄露,個人以為改為類似于系統調用ssize_t read (void * buf, unsinged long)的接口更為合理,由返回值指出實際所讀取數據的長度,而第二個參數來指定上層用戶所使用的緩沖區的大小,但若這樣實現必須考慮用戶一次無法讀取所以數據的情況。  回復  更多評論   

# re: 輪子:FTP接口實現 2009-09-10 21:42 白云深

暈,剛才又仔細看了下,那個接口好像在實際應用中并不會被調用,這樣的話上面我懷疑的問題也就不是問題了。  回復  更多評論   

# re: 輪子:FTP接口實現 2009-09-12 22:17 codejie

@白云深
這里先說明一下Read和Write,這兩個函數和Port或者Pasv方式沒有關系,就是從Socket上讀數據和寫數據,因此這兩個函數放在FTP數據傳輸鏈路的基類CFTPDataTcpObject中。兩個函數不同的參數完成不同的需求,如下:
int Read(char*& data, size_t& size);
用于從Socket接收數據到data中,接收的長度放在size中返回;
int Read(std::ofstream& ofile, size_t& size);
用于從Scket接收數據到文件ofile中,接收的長度放在size中返回;
int Read(std::ostream& os, size_t& size);
用于從Socket接收數據到輸出流os中,接收的長度放在size中返回;
int Write(const char* data, size_t size);
用于將data中的數據寫入到Socket中;
int Write(std::ifstream& ifile, size_t& size);
用于將輸入文件ifile的數據寫入到Socket中;

在我們使用中,FTP數據操作多數是針對文件的,因此下面兩個函數方式是最常用的:
int Read(std::ofstream& ofile, size_t& size);
int Write(std::ifstream& ifile, size_t& size);

因此,我覺得你嘗試覆蓋上面的函數應該會被調用到,除非你不是針對文件操作,就像使用FTP的LIST命令,是將結果放在輸出流或者一塊空間中。

關于你的問題:
1.String代替data,這種方式是可行的,只是使用起來應該比較危險和不方便,雖然string可以存放非可見字符,但顯示中很少用string來操作他們;簡單地說,你不能確定FTP只是傳文本文件吧?傳個圖片什么的,FTP應該支持吧?
2.關于data被new而沒有delete的問題,先看看函數聲明:
int Read(char*& data, size_t& size);
可見data是傳出參數,如果函數里面就delete了,那調用這個函數還有什么意義呢?如果data由調用方new好,但調用方(上層程序)又怎么預先知道new多少空間夠呢?這種由函數自己new,而由調用方管理的定義方式應該算常見的,簡單說當使用類似(char*&)這樣的參數時,就該意識到,使用者有義務管理好返回的指針。(多說一句:函數參數char*和char*&是不同的)
  回復  更多評論   

# re: 輪子:FTP接口實現 2009-09-14 23:20 白云深

受教了。

呵呵,看著又是指針又是引用有點暈,還是自己寫的代碼太少了。  回復  更多評論   

公告

Using C++

導航

統計

留言簿(73)

隨筆分類(513)

積分與排名

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产在线不卡精品| 欧美一区二区在线免费播放| 香蕉久久夜色精品| 性欧美大战久久久久久久久| 欧美一区二区三区四区夜夜大片| 亚洲欧美国产三级| 久久久久久久综合色一本| 欧美+亚洲+精品+三区| 亚洲国产精品黑人久久久| 欧美高清视频在线| 亚洲人成绝费网站色www| 一区二区三区免费在线观看| 午夜精品一区二区三区在线视| 久久免费国产精品| 欧美日韩精品伦理作品在线免费观看| 国产精品日韩二区| 亚洲国产欧美在线人成| 中日韩视频在线观看| 久久久夜色精品亚洲| 亚洲毛片在线看| 欧美在线一二三| 午夜精品福利一区二区三区av | 欧美揉bbbbb揉bbbbb| 国产精品自拍小视频| 亚洲黄一区二区三区| 香蕉av777xxx色综合一区| 欧美成va人片在线观看| 亚洲一区综合| 欧美精选一区| 亚洲成人资源网| 欧美影院在线播放| 亚洲日本中文字幕| 久久精品一区四区| 国产精品一区久久| 亚洲视频一区在线| 亚洲福利专区| 美国十次了思思久久精品导航| 国产女主播视频一区二区| 亚洲视频在线一区| 亚洲精品五月天| 欧美69wwwcom| 亚洲电影欧美电影有声小说| 久久一二三四| 久久久久久久久蜜桃| 国产有码在线一区二区视频| 亚洲影院在线观看| 一本大道久久a久久综合婷婷| 欧美成人亚洲成人日韩成人| 亚洲国产欧美一区二区三区久久| 麻豆成人综合网| 久久九九国产精品| 一区二区三区在线免费播放| 久久久女女女女999久久| 欧美亚洲三级| 精品99视频| 亚洲福利视频网站| 欧美激情视频网站| 99精品福利视频| 亚洲另类春色国产| 国产精品xxxav免费视频| 亚洲一区二区三区高清| 一本色道久久88精品综合| 国产精品毛片va一区二区三区 | 欧美在线视频一区二区| 精品69视频一区二区三区| 美女在线一区二区| 蜜乳av另类精品一区二区| 亚洲精品国产视频| 亚洲韩国青草视频| 欧美日韩国产一区二区三区地区| 一区二区欧美精品| 亚洲一区国产| 激情自拍一区| 亚洲人www| 国产精品亚洲片夜色在线| 国产日韩亚洲欧美精品| 欧美成人中文字幕在线| 在线观看一区二区精品视频| 欧美二区在线看| 欧美极品在线播放| 亚洲欧美激情四射在线日| 亚洲欧美在线x视频| 黄色资源网久久资源365| 亚洲国产欧美不卡在线观看| 欧美性猛交xxxx乱大交退制版| 欧美亚洲综合在线| 免费人成精品欧美精品| 午夜精品理论片| 久久先锋影音av| 夜夜嗨av色一区二区不卡| 亚洲风情在线资源站| 免费成人av在线看| 玖玖综合伊人| 欧美高清视频在线播放| 亚洲一区综合| 久久日韩粉嫩一区二区三区| 夜夜嗨av色综合久久久综合网| 亚洲影院免费| 日韩视频一区二区三区| 亚洲欧美日韩一区二区| 亚洲国产日日夜夜| 亚洲嫩草精品久久| 一本色道婷婷久久欧美| 久久夜色精品一区| 久久精品国产清高在天天线| 欧美日本精品一区二区三区| 久久综合九色综合久99| 国产精品久久久对白| 亚洲国产成人av| 黄色精品网站| 午夜精品福利在线观看| 亚洲午夜久久久久久久久电影院 | 亚洲人成绝费网站色www| 国产一区二区三区无遮挡| 一区二区三区视频在线看| 亚洲欧洲精品一区二区三区波多野1战4 | 亚洲欧洲日本在线| 欧美尤物巨大精品爽| 一本到12不卡视频在线dvd| 老鸭窝91久久精品色噜噜导演| 久久国产精品久久久久久| 国产精品第一页第二页第三页| 亚洲激情婷婷| 亚洲日本欧美天堂| 久久久综合香蕉尹人综合网| 久久久久久久激情视频| 国产亚洲欧美aaaa| 欧美伊人久久久久久久久影院| 午夜在线视频观看日韩17c| 国产精品播放| 亚洲男人第一网站| 久久精品中文| 亚洲大片在线| 欧美日韩免费一区| 亚洲午夜极品| 亚洲婷婷在线| 国产精品国产三级国产aⅴ浪潮| 亚洲经典三级| 夜色激情一区二区| 欧美区日韩区| 亚洲视频一区在线| 久久精品国产91精品亚洲| 国产一区二区久久精品| 久久国产视频网| 欧美18av| 亚洲精品一区二区在线观看| 免费欧美在线视频| 亚洲美女色禁图| 亚洲欧美在线另类| 国产麻豆午夜三级精品| 欧美在线亚洲一区| 亚洲国产免费看| 亚洲综合日韩| 国产亚洲一级| 欧美国产免费| 亚洲影视九九影院在线观看| 久久中文字幕一区二区三区| 亚洲人成小说网站色在线| 欧美视频精品在线| 欧美在线亚洲| 日韩视频二区| 久久伊人一区二区| 亚洲毛片在线看| 国产欧美69| 欧美黄色影院| 小处雏高清一区二区三区| 91久久精品久久国产性色也91| 欧美一区二区三区电影在线观看| 亚洲福利视频一区二区| 国产精品久久一级| 欧美成人午夜77777| 亚洲综合成人在线| 欧美激情第3页| 午夜视频一区在线观看| 亚洲三级国产| 国内精品久久久久久久97牛牛| 欧美日韩国产91| 久久久人成影片一区二区三区| 夜夜爽www精品| 欧美国产在线观看| 久久av一区二区三区| 亚洲视频久久| 亚洲三级国产| 狠狠做深爱婷婷久久综合一区 | 夜夜嗨av一区二区三区网站四季av| 久久亚洲春色中文字幕| 亚洲午夜激情| 夜夜夜久久久| 亚洲欧洲一区二区在线播放| 国产欧美一区二区精品仙草咪| 欧美波霸影院| 久久九九热re6这里有精品| 亚洲婷婷在线| 亚洲老板91色精品久久| 亚洲国产精品va在线看黑人动漫| 久久精品成人| 欧美一区二区三区在线播放| 亚洲视频图片小说| 亚洲少妇中出一区| 亚洲色无码播放|