当前位置 主页 > 服务器问题 > win服务器问题汇总 >

    python 实现简单的FTP程序

    栏目:win服务器问题汇总 时间:2019-12-31 00:51

    FTP即文件传输协议;它基于客户机-服务器模型体系结构,应用广泛。它有两个通道:一个命令通道和一个数据通道。命令通道用于控制通信,数据通道用于文件的实际传输。使用FTP可以做很多事情,比如移动、下载、复制文件等。

    一、开发环境

    server端:centos 7  python-3.6.2

    客户端:Windows 7 python-3.6.2 pycharm-2018

    程序目的:1、学习使用socketserver实现并发处理多个客户端。

                 2、了解使用struct解决TCP粘包。

    二、程序设计

    (本人菜鸟一枚,对于开发规范,接口设计完全不懂,完全是随心所欲,自娱自乐。写博客主要是记录自己学习的点点滴滴,如有不足之处还请见谅。)

    1、server端

    1.1 目录结构如下:

     1.2 目录简介:

    FTP_SERVER:程序主目录

    app:程序主逻辑目录,目录下有四个模块:

              FTPserver.py:FTP  Server端启动入口。

              login.py:认证注册模块,用于处理用户注册,登录认证。

              dataAnalysis.py:命令解析模块,负责解析,执行客户端命令。

              FileOpertion.py:负责文件读,写。数据发送,数据接收。

    db:存放user_pwd.db文件,用于存放用户信息(用户名,密码,FTP目录总空间,已使用空间等)

    lib:存放公共数据。

    1.3 模块中类的继承关系

    1.4 执行流程

    1.4.1 程序启动文件FTPserver.py,程序启动后进入监听状态。核心代码如下:

    class MyFtpServer(socketserver.BaseRequestHandler):
     
     def handle(self): # 重写handle方法,处理socket请求
     print(f"连接来自{self.client_address}的客户端")
     commom_obj = Commom()
     data_analy = DataAnalysis()
     login_obj = Login()
     while 1:
     # 执行用户选项:1、登陆系统 2、注册账号。并返回一个结果
     status_id = login_obj.run_client_choice(self.request, commom_obj)
     if status_id == "01": # 登陆成功
     if not self.run_ftp_server(data_analy,commom_obj): # 执行ftpserver主功能
      break
     elif int(status_id) == -1: # client断开连接了
     break
     print(f"客户端{self.client_address}断开了连接")
    
     def run_ftp_server(self,data_analy,commom_obj):
     """"
     登陆成功后,接收客户端发来的命令,并进行处理
     :param data_analy:负责解析,执行客户端命令的对象
     :param commom_obj:程序执行时所需的数据对象
     :return 返回false代表客户端断开连接了
     """
     while True:
     try:
     cmd_len_pack = self.request.recv(4) 
     cmd_len = struct.unpack('i',cmd_len_pack)[0] # 获取命令长度,防止粘包 
     except Exception:
     break
     recv_data = self.request.recv(cmd_len).decode('utf-8') # 接收客户端数据
     if recv_data.upper() == "Q": # 客户端提出断开连接了
     break
     # 解析,处理客户端的命令
     data_analy.syntax_analysis(recv_data, self.request, commom_obj)
     return False
    if __name__ == '__main__':
     print('运行FTP服务')
     ip_port = ('192.168.10.10',9000)
     # 创建并发服务端对象
     server = socketserver.ThreadingTCPServer(ip_port, MyFtpServer)
     # 开启服务
     server.serve_forever()