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

Codejie's C++ Space

Using C++

輪子:FTP接口實(shí)現(xiàn)

項(xiàng)目中新增對(duì)FTP的支持,需求的變更是開發(fā)過程中不可避免的事情,只是變更的時(shí)間越靠近項(xiàng)目末期,就越是災(zāi)難。還好這個(gè)需求可以設(shè)計(jì)的相對(duì)獨(dú)立,做到盡量不影響已實(shí)現(xiàn)部分。
???? 說的FTP,就想起曾經(jīng)寫的一個(gè)FTP接口對(duì)象,由于現(xiàn)在FTP的實(shí)現(xiàn)庫(kù)到處都是,因此在寫好此對(duì)象時(shí),被同事稱為:做輪子的人~我的想法是,組裝車和制作車應(yīng)該還是有區(qū)別的~
???? 不扯了,下面是實(shí)現(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;
}


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

評(píng)論

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-08-06 14:27 uwinb

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

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-08-06 17:28 codejie

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

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-08-08 19:19 uwinb

FTP其實(shí)就是個(gè)有問有答的協(xié)商協(xié)議,Pasv和Port只不過是兩種登錄的方式,在我的方案中發(fā)現(xiàn)其中一種失效會(huì)自動(dòng)去嘗試另一種,不管咋的建立聯(lián)接以后的數(shù)據(jù)傳遞沒啥子區(qū)別。所以對(duì)你的類框架模型稍有質(zhì)疑,呵呵!
還有涉及訪問網(wǎng)絡(luò)這種充滿不可預(yù)測(cè)的事件的對(duì)象,你居然不使用異常來反饋錯(cuò)誤!學(xué)術(shù)討論而已,不必介意我的觀點(diǎn)。  回復(fù)  更多評(píng)論   

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-08-09 20:16 codejie

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

我很介意你的觀點(diǎn),因?yàn)槲艺J(rèn)為--不同的思想只有去碰撞,才能共同改善~  回復(fù)  更多評(píng)論   

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-09-08 19:57 白云深

謝謝樓主的代碼。

另外有個(gè)問題請(qǐng)教一下:“ACEX_TcpStream”這個(gè)對(duì)象是什么庫(kù)里面的,還是樓主自己封裝的?  回復(fù)  更多評(píng)論   

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-09-08 22:38 codejie

客氣了~
ACEX_TcpStream類是對(duì)Socket的封裝,出自工作中使用的ACEX庫(kù),這個(gè)不是我封的,從功能看應(yīng)該基于Socket和Stream兩個(gè)基類。把這個(gè)類看成Socket流對(duì)象就可以了,這個(gè)不是重點(diǎn)了。  回復(fù)  更多評(píng)論   

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-09-08 23:31 白云深

多謝樓主答復(fù)。

本人是個(gè)菜鳥,所以細(xì)節(jié)上有好多問題不明白。  回復(fù)  更多評(píng)論   

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-09-09 21:32 codejie

客氣了~有問題,咱一起想~  回復(fù)  更多評(píng)論   

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-09-09 21:46 白云深

呵呵,謝謝樓主的熱心。

雖然不恥下問是個(gè)好習(xí)慣,但基礎(chǔ)的東西還是要靠自己的學(xué)習(xí),自己不學(xué)習(xí)隨意張口問別人也不是學(xué)習(xí)的好態(tài)度,同時(shí)也是浪費(fèi)別人的時(shí)間和自己的智商。不說了,學(xué)習(xí)了,呵呵。以后會(huì)經(jīng)常來博主這,向博主請(qǐng)益,博主可要勤奮點(diǎn)哦,博主多寫文章就是對(duì)俺們菜鳥最大的幫助。  回復(fù)  更多評(píng)論   

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-09-09 22:35 codejie

求你多來問吧,么發(fā)現(xiàn)近來代碼越來越少了嗎?這里都成了我發(fā)牢騷的地方了。你的問題也是讓我前進(jìn)的動(dòng)力~  回復(fù)  更多評(píng)論   

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-09-10 21:39 白云深

今天把博主的代碼整理了一下,暫時(shí)調(diào)試了一下port模式。把下面這個(gè)函數(shù)

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

改為:

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

博主的實(shí)現(xiàn)中,用new來動(dòng)態(tài)分配內(nèi)存,但好像沒有釋放,按博主的實(shí)現(xiàn),這個(gè)釋放動(dòng)作應(yīng)該要由上層調(diào)用來完成,不知道我的理解是否正確。如果所說無誤,這是否可以理解為這個(gè)接口會(huì)造成泄漏或與上層程序有耦合?

另外,如果不用std::string來返回?cái)?shù)據(jù)以防止內(nèi)存泄露,個(gè)人以為改為類似于系統(tǒng)調(diào)用ssize_t read (void * buf, unsinged long)的接口更為合理,由返回值指出實(shí)際所讀取數(shù)據(jù)的長(zhǎng)度,而第二個(gè)參數(shù)來指定上層用戶所使用的緩沖區(qū)的大小,但若這樣實(shí)現(xiàn)必須考慮用戶一次無法讀取所以數(shù)據(jù)的情況。  回復(fù)  更多評(píng)論   

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-09-10 21:42 白云深

暈,剛才又仔細(xì)看了下,那個(gè)接口好像在實(shí)際應(yīng)用中并不會(huì)被調(diào)用,這樣的話上面我懷疑的問題也就不是問題了。  回復(fù)  更多評(píng)論   

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-09-12 22:17 codejie

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

在我們使用中,F(xiàn)TP數(shù)據(jù)操作多數(shù)是針對(duì)文件的,因此下面兩個(gè)函數(shù)方式是最常用的:
int Read(std::ofstream& ofile, size_t& size);
int Write(std::ifstream& ifile, size_t& size);

因此,我覺得你嘗試覆蓋上面的函數(shù)應(yīng)該會(huì)被調(diào)用到,除非你不是針對(duì)文件操作,就像使用FTP的LIST命令,是將結(jié)果放在輸出流或者一塊空間中。

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

# re: 輪子:FTP接口實(shí)現(xiàn) 2009-09-14 23:20 白云深

受教了。

呵呵,看著又是指針又是引用有點(diǎn)暈,還是自己寫的代碼太少了。  回復(fù)  更多評(píng)論   

公告

Using C++

導(dǎo)航

統(tǒng)計(jì)

留言簿(73)

隨筆分類(513)

積分與排名

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久这里只精品最新地址| 欧美一区不卡| 亚洲精品视频免费观看| 91久久综合亚洲鲁鲁五月天| 亚洲国产天堂久久综合| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲裸体在线观看| 欧美一级片在线播放| 亚洲二区视频在线| 欧美一区二区大片| 禁久久精品乱码| 性色av香蕉一区二区| 亚洲欧美精品在线| 欧美日本成人| 黄色免费成人| 午夜国产精品视频免费体验区| 亚洲第一精品福利| 国产精品草草| 亚洲精选一区| 亚洲免费影视| 亚洲大黄网站| 久久久伊人欧美| 亚洲综合精品| 亚洲日本一区二区| 亚洲免费在线看| 亚洲国产一二三| 亚洲一本大道在线| 欧美香蕉大胸在线视频观看| 久久精品成人一区二区三区| 亚洲资源在线观看| 亚洲国产精品悠悠久久琪琪| 亚洲视频免费观看| 国产精品一区在线观看你懂的| 一区二区三区蜜桃网| 欧美激情精品久久久久久变态| 欧美伊人久久| 国产一区二区三区四区hd| 午夜伦理片一区| 欧美成人黑人xx视频免费观看| 在线观看福利一区| 欧美搞黄网站| 女人色偷偷aa久久天堂| 亚洲国产视频a| 亚洲欧美日本国产专区一区| 欧美日本精品| 女仆av观看一区| 免费日本视频一区| 久久久久久久尹人综合网亚洲| 久久国产精品久久w女人spa| 一区二区三区在线高清| 亚洲综合日韩在线| 亚洲视频一区| 欧美亚洲视频在线看网址| 亚洲视频在线免费观看| 欧美freesex交免费视频| 久久这里有精品视频| 国产日韩视频| 欧美激情2020午夜免费观看| 韩国成人福利片在线播放| 午夜精品成人在线| 欧美一级专区免费大片| 久久亚洲综合色| 99精品热视频只有精品10| 一本色道久久88亚洲综合88| 国产亚洲精品自拍| 亚洲欧美一区二区三区在线| 午夜精品一区二区三区在线| 欧美三区美女| 久久亚洲一区二区三区四区| 国产主播精品| 亚洲精品社区| 这里是久久伊人| 欧美日韩在线不卡| 久久久免费观看视频| 久久久av水蜜桃| 亚洲欧美日韩一区二区| 欧美一级黄色网| 国产亚洲精品久| 久久嫩草精品久久久久| 亚洲大胆美女视频| 欧美日韩免费一区二区三区| 日韩亚洲一区二区| 亚洲国产毛片完整版| 蜜桃av综合| 久久久久久久久久久久久女国产乱 | 欧美一级淫片播放口| 国产午夜久久久久| 久久久亚洲午夜电影| 亚洲欧洲99久久| 国产亚洲成精品久久| 久久久久久久久综合| 亚洲欧洲精品一区| 亚洲欧美日韩精品久久久久| 老**午夜毛片一区二区三区| 亚洲一区二区三区精品在线 | 久久久久一区二区三区四区| 亚洲国产精品一区| 欧美一区二视频| **性色生活片久久毛片| 欧美电影免费网站| 一本大道久久a久久综合婷婷 | 欧美日韩精品高清| 欧美福利电影在线观看| 一本久道久久综合婷婷鲸鱼| 免费在线观看精品| 中国成人亚色综合网站| 久久综合中文| 韩国女主播一区| 欧美日韩性生活视频| 欧美综合77777色婷婷| 亚洲免费成人av| 欧美a级一区| 午夜精品三级视频福利| 亚洲狠狠婷婷| 国产亚洲欧美激情| 欧美日韩午夜视频在线观看| 久久婷婷人人澡人人喊人人爽 | 免费亚洲一区| 亚洲国产精品va在线看黑人| 欧美极品一区二区三区| 欧美电影美腿模特1979在线看 | 国产亚洲aⅴaaaaaa毛片| 欧美国产亚洲视频| 亚洲美女黄网| 欧美成人自拍视频| 久久久久久久久久看片| 亚洲在线一区二区三区| 国产精品亚洲综合色区韩国| 亚洲一区制服诱惑| 久久成人精品电影| 国产午夜精品麻豆| 国产精品wwwwww| 欧美另类人妖| 欧美精品1区2区| 欧美+亚洲+精品+三区| 亚洲视频导航| 亚洲日韩中文字幕在线播放| 一色屋精品视频在线观看网站| 国产精品一区免费视频| 国产精品高潮呻吟视频| 欧美一级大片在线免费观看| 亚洲深夜福利网站| 亚洲天堂成人在线观看| 一区二区三区成人精品| 在线午夜精品自拍| 在线视频欧美一区| 亚洲午夜激情免费视频| 亚洲午夜精品网| 午夜电影亚洲| 久久不射电影网| 久久在线观看视频| 欧美1区2区| 欧美日韩精品一区视频| 欧美三区免费完整视频在线观看| 欧美日韩精选| 国产精品日韩一区二区| 欧美va亚洲va香蕉在线| 国产精品久久久久久av下载红粉| 国产精品久久久久久久久久免费| 午夜精品一区二区三区四区| 亚洲黄色在线观看| 亚洲精品午夜| 亚洲欧美成人| 久久人人爽国产| 欧美精品久久久久久久久久| 欧美日韩亚洲在线| 国产乱码精品一区二区三区忘忧草| 国产麻豆日韩| 激情综合色综合久久综合| 亚洲黄网站在线观看| 亚洲一区二区三区涩| 久久aⅴ国产欧美74aaa| 免费日韩成人| 亚洲精品国产精品国自产观看浪潮| 欧美在线观看视频| 欧美成人精品1314www| 日韩视频一区二区在线观看| 亚洲欧美精品伊人久久| 久久在线免费观看| 欧美日韩视频一区二区三区| 国产欧美日韩综合精品二区| 国产精品久久二区| 伊人影院久久| 亚洲综合丁香| 欧美国产欧美亚洲国产日韩mv天天看完整 | 日韩午夜激情电影| 久久激情综合网| 欧美日韩精品在线播放| 影音先锋久久久| 亚洲欧美区自拍先锋| 欧美大片第1页| 性8sex亚洲区入口| 欧美美女喷水视频| 在线国产日韩| 欧美一区二区三区在| 亚洲精选中文字幕| 老司机久久99久久精品播放免费| 国产精品麻豆欧美日韩ww| 99www免费人成精品| 麻豆亚洲精品|