使用c++实现一个FTP客户端(二)

  接上篇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 };
原文地址:https://www.cnblogs.com/jzincnblogs/p/5217688.html