⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpclient.h

📁 实现了wince 客户端上传下载查看文件及目录的功能接口d
💻 H
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////////////
//
// The official specification of the File Transfer Protocol (FTP) is the RFC 959.
// Most of the documentation are taken from this RFC.
// This is an implementation of an simple ftp client. I have tried to implement
// platform independent. For the communication i used the classes CBlockingSocket,
// CSockAddr, ... from David J. Kruglinski (Inside Visual C++). These classes are
// only small wrappers for the sockets-API.
// Further I used a smart pointer-implementation from Scott Meyers (Effective C++, 
// More Effective C++, Effective STL).
// The implementation of the logon-sequence (with firewall support) was published 
// in an article on Codeguru by Phil Anderson. 
// The code for the parsing of the different FTP LIST responses is taken from 
// D. J. Bernstein (http://cr.yp.to/ftpparse.html). I only wrapped the c-code in
// a class.
// I haven't tested the code on other platforms, but i think with little 
// modifications it would compile.
// 
// Copyright (c) 2004 Thomas Oswald
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
//
////////////////////////////////////////////////////////////////////////////////

#ifndef INC_FTPCLIENT_H
#define INC_FTPCLIENT_H

// STL-includes
#include <memory>
#include <queue>

// other includes
#include "FTPDataTypes.h"
#include "BlockingSocket.h"
#include "FTPFileState.h"

////////////////////////////////////////////////////////////////////////////////
/// Namespace for all FTP-related classes.
////////////////////////////////////////////////////////////////////////////////
namespace nsFTP
{
   typedef std::vector<tstring> TStringVector;

   using namespace nsSocket;

   class ITransferNotification
   {
   public:
      virtual void OnBytesReceived(const TByteVector& /*vBuffer*/, long /*lReceivedBytes*/) {}
      virtual void OnPreBytesSend(TByteVector& /*vBuffer*/, size_t& /*bytesToSend*/) {}
   };

   /// @brief FTP client class
   ///
   /// Use this class for all the ftp-client stuff such as
   /// - logon server
   /// - send and receive data
   /// - get directory listing
   /// - ...
   ///
   class CFTPClient
   {
   public:
	   static CFTPClient* Instance();

      class CNotification;
      class TObserverSet : public nsHelper::CObserverPatternBase<CNotification*, TObserverSet*> {};

      CFTPClient(IBlockingSocket* pSocket=nsSocket::CreateDefaultBlockingSocketInstance(),
                 unsigned int uiTimeout=10, unsigned int uiBufferSize=2048, unsigned int uiResponseWait=0);
      virtual ~CFTPClient();

      void AttachObserver(CNotification* pObserver);
      void DetachObserver(CNotification* pObserver);

      bool IsConnected() const;
      bool IsTransferringData() const;
      void SetResumeMode(bool fEnable=true);

      bool Login(const CLogonInfo& loginInfo);
      int  Logout();
      const CLogonInfo& LastLogonInfo() const { return m_LastLogonInfo; }

      bool List(const tstring& strPath, TStringVector& vstrFileList, bool fPasv=false) const;
      bool NameList(const tstring& strPath, TStringVector& vstrFileList, bool fPasv=false) const;

      bool List(const tstring& strPath, TSpFTPFileStatusVector& vFileList, bool fPasv=false) const;
      bool NameList(const tstring& strPath, TSpFTPFileStatusVector& vFileList, bool fPasv=false) const;

      int  Delete(const tstring& strFile) const;
      int  Rename(const tstring& strOldName, const tstring& strNewName) const;
      bool DownloadFile(const tstring& strRemoteFile, const tstring& strLocalFile,
                        const CRepresentation& repType=CRepresentation(CType::Image()), bool fPasv=true) const;
      bool UploadFile(const tstring& strLocalFile, const tstring& strRemoteFile, bool fStoreUnique=false, 
                      const CRepresentation& repType=CRepresentation(CType::Image()), bool fPasv=true) const;
      int  RemoveDirectory(const tstring& strDirectory) const;
      int  MakeDirectory(const tstring& strDirectory) const;

      int PrintWorkingDirectory() const;
      int ChangeToParentDirectory() const;
      int ChangeWorkingDirectory(const tstring& strDirectory) const;

      int Passive(ULONG& ulIpAddress, USHORT& ushPort) const;
      int DataPort(const tstring& strHostIP, USHORT ushPort) const;
      int Abort() const;
      int System() const;
      int Noop() const;
      int RepresentationType(const CRepresentation& repType, DWORD dwSize=0) const;
      int FileStructure(const CStructure& crStructure) const;
      int TransferMode(const CTransferMode& crTransferMode) const;
      int Allocate(int iReserveBytes, const int* piMaxPageOrRecordSize=NULL) const;
      int StructureMount(const tstring& strPath) const;
      int SiteParameters(const tstring& strCmd) const;
      int Status(const tstring& strPath) const;
      int Help(const tstring& strTopic) const;

      int Reinitialize() const;
      int Restart(DWORD dwPosition) const;

      int FileSize(const tstring& strPath, long& lSize) const;
      int FileModificationTime(const tstring& strPath, tm& tmModificationTime) const;
      int FileModificationTime(const tstring& strPath, tstring& strModificationTime) const;

   protected:
      bool ExecuteDatachannelCommand(const CDatachannelCmd& crDatachannelCmd, const tstring& strPath, const CRepresentation& representation, 
                                     bool fPasv, DWORD dwByteOffset, ITransferNotification* pObserver) const;

      TObserverSet& GetObservers();
	   CLogonInfo                             m_LastLogonInfo;            ///< logon-info, which was used at the last call of login

   private:
      bool TransferData(const CDatachannelCmd& crDatachannelCmd, ITransferNotification* pObserver, IBlockingSocket& sckDataConnection) const;
      bool OpenActiveDataConnection(IBlockingSocket& sckDataConnection, const CDatachannelCmd& crDatachannelCmd, const tstring& strPath, DWORD dwByteOffset) const;
      bool OpenPassiveDataConnection(IBlockingSocket& sckDataConnection, const CDatachannelCmd& crDatachannelCmd, const tstring& strPath, DWORD dwByteOffset) const;
      bool SendData(ITransferNotification* pObserver, IBlockingSocket& sckDataConnection) const;
      bool ReceiveData(ITransferNotification* pObserver, IBlockingSocket& sckDataConnection) const;

      tstring GetCmdString(const CDatachannelCmd& crDatachannelCmd, const tstring& strPath) const;
      int  SimpleErrorCheck(const CReply& Reply) const;

      bool SendCommand(const tstring& strCommand) const;
      bool SendCommand(const tstring& strCommand, CReply& Reply) const;
      bool GetResponse(CReply& Reply) const;
      bool GetSingleResponseLine(tstring& strResponse) const;

      bool OpenControlChannel(const tstring& strServerHost, USHORT ushServerPort=DEFAULT_FTP_PORT);
      void CloseControlChannel();

      void ReportError(const tstring& strErrorMsg, const tstring& strFile, DWORD dwLineNr) const;
      bool GetIpAddressFromResponse(const tstring& strResponse, ULONG& ulIpAddress, USHORT& ushPort) const;

// data members
   private:
      const unsigned int                     mc_uiTimeout;               ///< timeout for socket-functions
      const unsigned int                     mc_uiResponseWait;          ///< sleep time between receive calls to socket when getting the response
      const tstring                          mc_strEolCharacterSequence; ///< end-of-line sequence of current operating system

      mutable TByteVector                    m_vBuffer;                  ///< buffer for sending and receiving
      mutable std::queue<std::string>        m_qResponseBuffer;          ///< buffer for server-responses
      mutable std::auto_ptr<CRepresentation> m_apCurrentRepresentation;  ///< representation currently set

      std::auto_ptr<IBlockingSocket>         m_apSckControlConnection;   ///< socket for connection to ftp-server
      mutable bool                           m_fTransferInProgress;      ///< if true, a file transfer is in progress
      mutable bool                           m_fAbortTransfer;           ///< indicates that a running filetransfer should be canceled
      bool                                   m_fResumeIfPossible;        ///< try to resume download/upload if possible
      TObserverSet                           m_setObserver;              ///< list of observers, which are notified about particular actions
     
	  static CFTPClient* pinstance;
   };

   /// @brief interface for notification
   ///
   /// Derive your class from this base-class and register this class on CFTPClient.
   /// For example you can use this for logging the sended and received commands.
   class CFTPClient::CNotification : public nsHelper::CObserverPatternBase<CFTPClient::TObserverSet*, CFTPClient::CNotification*>
   {
   public:
      virtual void OnInternalError(const tstring& /*strErrorMsg*/, const tstring& /*strFileName*/, DWORD /*dwLineNr*/) {}

      virtual void OnBeginReceivingData() {}
      virtual void OnEndReceivingData(long /*lReceivedBytes*/) {}
      virtual void OnBytesReceived(const TByteVector& /*vBuffer*/, long /*lReceivedBytes*/) {}
      virtual void OnBytesSent(const TByteVector& /*vBuffer*/, long /*lSentBytes*/) {}

      virtual void OnPreReceiveFile(const tstring& /*strSourceFile*/, const tstring& /*strTargetFile*/, long /*lFileSize*/) {}
      virtual void OnPreSendFile(const tstring& /*strSourceFile*/, const tstring& /*strTargetFile*/, long /*lFileSize*/) {}
      virtual void OnPostReceiveFile(const tstring& /*strSourceFile*/, const tstring& /*strTargetFile*/, long /*lFileSize*/) {}
      virtual void OnPostSendFile(const tstring& /*strSourceFile*/, const tstring& /*strTargetFile*/, long /*lFileSize*/) {}

      virtual void OnSendCommand(const tstring& /*strCommand*/) {}
      virtual void OnResponse(const CReply& /*Reply*/) {}
   };
}

#endif // INC_FTPCLIENT_H

// FTP commands - Overview

// simple commands
//   CDUP <CRLF>
//   QUIT <CRLF>
//   REIN <CRLF>
//   PASV <CRLF>
//   STOU <CRLF>
//   ABOR <CRLF>
//   PWD  <CRLF>
//   SYST <CRLF>
//   NOOP <CRLF>
//   PORT <SP> <host-port> <CRLF>
//   TYPE <SP> <type-code> <CRLF>
//   CWD  <SP> <pathname> <CRLF>
//   MKD  <SP> <pathname> <CRLF>
//   SITE <SP> <string> <CRLF>
//   HELP [<SP> <string>] <CRLF>
//   DELE <SP> <pathname> <CRLF>
//   RMD  <SP> <pathname> <CRLF>
//   STRU <SP> <structure-code> <CRLF>
//   MODE <SP> <mode-code> <CRLF>
//   STAT [<SP> <pathname>] <CRLF>
//   ALLO <SP> <decimal-integer>
//       [<SP> R <SP> <decimal-integer>] <CRLF>
//   SMNT <SP> <pathname> <CRLF>

// commands for logon sequence
//   USER <SP> <username> <CRLF>
//   PASS <SP> <password> <CRLF>
//   ACCT <SP> <account-information> <CRLF>

// commands for renaming
//   RNFR <SP> <pathname> <CRLF>
//   RNTO <SP> <pathname> <CRLF>

//   RETR <SP> <pathname> <CRLF>
//   STOR <SP> <pathname> <CRLF>
//   APPE <SP> <pathname> <CRLF>
//   REST <SP> <marker> <CRLF>
//   LIST [<SP> <pathname>] <CRLF>
//   NLST [<SP> <pathname>] <CRLF>

// non RFC-Commands
//   SIZE <SP> <pathname> <CRLF>
//   MDTM <SP> <pathname> <CRLF>

/** \class nsFTP::CStructure
   In addition to different representation types, FTP allows the
   structure of a file to be specified.  Three file structures are
   defined in FTP:

      - file-structure,     where there is no internal structure and
                           the file is considered to be a
                           continuous sequence of data bytes,

      - record-structure,   where the file is made up of sequential
                           records,

      - and page-structure, where the file is made up of independent
                           indexed pages.

   File-structure is the default to be assumed if the STRUcture
   command has not been used but both file and record structures
   must be accepted for "text" files (i.e., files with TYPE ASCII
   or EBCDIC) by all FTP implementations.  The structure of a file
   will affect both the transfer mode of a file (see the Section
   on Transmission Modes) and the interpretation and storage of
   the file.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -