• <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>

            Codejie's C++ Space

            Using C++

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

            項目中新增對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;
            }


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

            評論

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

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

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

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

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

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

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

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

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

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

            謝謝樓主的代碼。

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

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

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

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

            多謝樓主答復。

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

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

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

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

            呵呵,謝謝樓主的熱心。

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

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

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

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

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

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

            改為:

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

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

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

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

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

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

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

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

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

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

            受教了。

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

            公告

            Using C++

            導航

            統(tǒng)計

            留言簿(73)

            隨筆分類(513)

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            久久亚洲国产最新网站| 亚洲va中文字幕无码久久不卡| 久久人人爽人人爽人人av东京热 | 99久久精品国产综合一区| 武侠古典久久婷婷狼人伊人| 久久96国产精品久久久| 久久亚洲AV无码精品色午夜麻豆 | 久久影院久久香蕉国产线看观看| 亚洲精品高清国产一线久久| 欧美麻豆久久久久久中文| 国产精品久久久久久一区二区三区 | 狠狠色丁香久久婷婷综合_中| 国产2021久久精品| 国产一级做a爰片久久毛片| 亚洲AV日韩精品久久久久久久| 欧美午夜A∨大片久久 | 久久综合给久久狠狠97色| 漂亮人妻被中出中文字幕久久| 久久久久久无码国产精品中文字幕 | 无码人妻精品一区二区三区久久久| 欧美久久综合九色综合| 久久精品无码av| 久久成人18免费网站| 欧美一区二区精品久久| 久久99精品国产99久久| aaa级精品久久久国产片| 国产精品久久久亚洲| 精品国产乱码久久久久久1区2区 | 久久国产精品99精品国产| 亚洲∧v久久久无码精品| 国产偷久久久精品专区| 伊人色综合久久天天人手人婷| 久久亚洲sm情趣捆绑调教| 久久亚洲AV无码精品色午夜| 狠狠综合久久综合88亚洲| 久久精品一本到99热免费| 亚洲愉拍99热成人精品热久久| 亚洲va中文字幕无码久久| 久久国产高潮流白浆免费观看| 2021久久精品国产99国产精品| 99久久99这里只有免费费精品|