接上篇http://www.cnblogs.com/jzincnblogs/p/5213978.html,這篇主要記錄編程方面的重點。
客戶端使用了Windows Socket提供的API,支持上傳、下載、刪除、查看文件,斷點續傳,二進制/ASCII模式切換,被動模式切換,記錄操作日志等功能。
代碼包含的類如下:
①MySocket類,對SOCKET進行了簡單的封裝
1 //對winsock SOCKET的封裝 2 class MySocket 3 { 4 public: 5 MySocket(); 6 //~MySocket(); 7 //重載向SOCKET類型轉換的運算符 8 operator SOCKET() const; 9 //設置地址信息 10 void SetAddrInfo(std::string host, int port); 11 bool Connect(); 12 //bool Disconnect(); 13 bool Create(int af = AF_INET, int type = SOCK_STREAM, int protocol = IPPROTO_TCP); 14 bool Close(); 15 //獲取主機ip 16 std::string GetHostIP() const; 17 //獲取主機端口 18 int GetPort() const; 19 private: 20 SOCKET sock; 21 SOCKADDR_IN addr_in; //記錄連接的服務器的地址信息 22 bool conn_flag; //判斷是否已連接 23 };
②Record類,存儲了客戶端與服務器的交互信息的數據結構
1 //枚舉類型,CMD代表命令信息,RES代表響應信息 2 enum log_type { CMD = 1, RES = 2 }; 3 4 //與服務器的交互信息 5 class Record 6 { 7 friend std::ostream & operator<<(std::ostream &os, const Record &rcd); 8 public: 9 Record(log_type t, std::string m); 10 Record(const Record &rcd); 11 Record & operator=(const Record &rcd); 12 //獲取信息內容 13 std::string GetMsg() const; 14 private: 15 log_type type; //信息類型 16 std::string msg; 17 };
③Logger類,負責控制傳輸端口的發送命令,接收服務器響應,記錄、顯示操作日志等功能,包含一個Record類的vector,用於存儲此次程序運行的信息
1 class Logger 2 { 3 public: 4 Logger(const std::string &host, int port); 5 ~Logger(); 6 Logger(const Logger &logger) = delete; 7 Logger & operator=(const Logger &logger) = delete; 8 //發送命令 9 void SendCmd(const std::string &cmd); 10 //接收來自服務器的響應 11 void RecvResponse(); 12 //記錄信息 13 void Log(log_type type, const std::string &cmd); 14 //獲取最后一條交互信息,用於驗證命令是否執行成功 15 std::string GetLastLog() const; 16 void DisplayLog() const; 17 private: 18 MySocket sock_cmd; //發送接收命令的socket 19 std::vector<Record> vec_rcd; //保存此次客戶端運行的交互信息 20 //將信息記錄到文本文件中 21 void WriteRecord(); 22 };
④File類,用於存儲文件信息的數據結構
1 class File 2 { 3 friend std::ostream & operator<<(std::ostream &os, const File &file); 4 public: 5 //斜杠代表根目錄 6 File(const std::string &n = "", const std::string &t = "", const int &s = 0, const std::string &p = "/"); 7 int GetSize() const; 8 private: 9 std::string name; 10 std::string path; 11 std::string create_time; 12 int size; 13 };
⑤FTPClient類,代碼的核心類
1 class FTPClient 2 { 3 public: 4 FTPClient(const string &host, int port); 5 bool Login(const string &usr, const string &pwd); 6 //進入被動模式 7 bool EnterPasvMode(); 8 //更新文件列表 9 void UpdateFileList(); 10 //獲取指定文件信息 11 File GetFileInfo(const string &f); 12 void DisplayLog() const; 13 //以二進制格式下載文件 14 bool DownloadBinary(const string &f); 15 //以ASCII格式下載文件 16 bool DownloadASCII(const string &f); 17 //上傳文件 18 bool Upload(const string &f, bool binary); 19 //刪除指定文件 20 bool Delete(const string &f); 21 //退出客戶端 22 bool Quit(); 23 private: 24 Logger logger; 25 MySocket sock_data; //用於傳輸數據的socket 26 string host; 27 int port; 28 // 29 void GetFileList(); 30 bool EnterASCIIMode(); //進入ASCII模式 31 bool EnterBinaryMode(); //進入二進制模式 32 };
