zoukankan      html  css  js  c++  java
  • FTP作业

    模拟实现一个FTP

    [博客地址](http://www.cnblogs.com/mologa-jie/p/8378070.html)

    1.作业需求

    ```
    角色:ftp_s(server)、ftp_c(client)、{事例用户:miao=passwd=>miao,abu=passwd=>abu}
    要求:
    开发简单的FTP:
    1. 用户登陆
    2. 上传/下载文件
    3. 不同用户家目录不同
    4. 查看当前目录下文件
    5. 充分使用面向对象知识
    ```

    2.需求分析



    1) 用户登录

    client
    '''用户加密认证'''
    class log_in(object):
    
        _flag=False
        _times = 1
        def __init__(self):
            pass
    
        def auth(self,user):
            while not self._flag:
                # value = getpass.getpass("33[35;1m请输入用户密码:33[0m") #terminal 模式下支持运行,不然会直接卡主
                value = input("33[35;1m请输入用户密码:33[0m").strip()
                md5_value = hashlib.md5(value.encode('utf-8')).hexdigest()
                new_member = (user,md5_value)
                new_member = str(new_member)
                new_member = "auth_" + new_member
                res = client_sock.auth_transform(new_member)
                if res is True:
                    print("welcome to my ftp.py server!")
                    self._flag =  True
                    return self._flag
                elif self._times < 3:
                    self._times += 1
                    print("33[31;1m密码错误,重新输入!33[0m")
                    continue
                else:
                    print("33[31;1m密码错误多次,请联系管理员。33[0m")
                    return self._flag
    
        def register(self,user):
            while not self._flag:
                # value = getpass.getpass("33[35;1m请输入用户密码:33[0m")
                value = input("33[35;1m请输入用户密码:33[0m").strip()
                # re_value = getpass.getpass("33[35;1m请再次输入用户密码:33[0m")
                re_value = input("33[35;1m请再次输入用户密码:33[0m").strip()
                if value == re_value:
                    print("33[34;1m注册中……!33[0m")
                    md5_value = hashlib.md5(value.encode('utf-8')).hexdigest()
                    new_member = (user,md5_value)
                    new_member = str(new_member)
                    new_member = "register_"+new_member
                    res = client_sock.auth_transform(new_member)
                    if self._flag != res:
                        return res
                    else:
                        print("注册失败!")
                        continue
                elif self._times < 3:
                    self._times += 1
                    print("33[31;1m密码不一致,重新输入!33[0m")
                    continue
                else:
                    print("33[31;1m密码错误多次,请联系管理员。33[0m")
                    return self._flag
    

      

    server
    '''用户加密认证'''
    class log_in(object):
    
        member_list=auth.auth_file().read_file()
    
        def auth(self,args):
            args = eval(args)
            if args in self.member_list.items():
                return True
            else:
                return False
    
        def register(self,args):
            self.member_list.update(args)
            auth.auth_file().write_file(self.member_list)
            return True
    

      



    `client`展示:
    ------- 欢迎进入FTP ---------

    1. 注册
    2. 登录
    3. 退出

    请选择:2
    请输入用户名:abu
    请输入用户密码:abu
    welcome to my ftp.py server!

    ------- abu个人空间 ---------

    1. 传输文件
    2. 命令交互
    3. 退出

    请选择:2

    ------- 命令行模式 ---------

    1. 当前用户根目录
    2. 支持常用命令{eq: ls }
    3. 退出 quit

    Sent: dir
    Received: 驱动器 F 中的卷是 生活
    卷的序列号是 1C94-79CB

    F:mologa-workspaceweek_5week-5ftp_suser_rootabu 的目录

    2018/01/29 14:21 <DIR> .
    2018/01/29 14:21 <DIR> ..
    2018/01/29 14:21 4,672,137 bible.txt
    1 个文件 4,672,137 字节
    2 个目录 298,844,962,816 可用字节

    Sent: quit
    =-=-=-=-=-=-=-=-=-=-=-=-=-=退出模块=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    ------- abu个人空间 ---------

    1. 传输文件
    2. 命令交互
    3. 退出

    请选择:3
    终止

    `server`log展示:

    127.0.0.1 request
    Mon Jan 29 15:50:08 2018 : abu 认证成功
    127.0.0.1 request
    Mon Jan 29 15:50:13 2018 : abu 执行 dir
    127.0.0.1 request
    Mon Jan 29 15:50:17 2018 : abu 用户退出!


    2)上传、下载


    client
    def recvfile(user,client_command):
        HOST, PORT = "localhost", 8888
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.connect((HOST, PORT))
        action,filename = client_command.split()
        file_path = os.path.join(((sys.path)[-1]), "user_home")
        f_path = os.path.join(file_path, user)
        filename = os.path.join(f_path, filename)
        if os.path.isfile(filename):
            print("文件已经存在!")
            return "fail"
        msg = "file_('%s','%s')"%(user,client_command)
        client.send(msg.encode())
        data = str(client.recv(1024),'utf-8')
        if data == 'ready':
            f = open(filename, 'wb')
            while True:
                data = client.recv(102400)
                if data == b'EOF':
                    print("recv file success!")
                    break
                f.write(data)
            f.close()
            return "success"
        else:
            print("文件下行错误!")
            return "fail"
    
    def sendfile(user,client_command):
        HOST, PORT = "localhost", 8888
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.connect((HOST, PORT))
        action, filename = client_command.split()
        file_path = os.path.join(((sys.path)[-1]), "user_home")
        f_path = os.path.join(file_path, user)
        filename = os.path.join(f_path, filename)
        if os.path.isfile(filename):
            msg = "file_('%s','%s')"%(user,client_command)
            client.send(msg.encode())
            flag = client.recv(1024)
            if flag == b'ready':
                f = open(filename, 'rb')
                while True:
                    data = f.read(102400)
                    if not data:
                        break
                    client.sendall(data)
                f.close()
                time.sleep(1)
                client.sendall('EOF'.encode())
                print("传输成功!")
                return "success"
            else:
                print("操作失败!")
                return "fail"
        else:
            print("文件不存在!")
            return "fail"
    

      


    server
    filename_c = (eval(args))[1]
    filec,filename = filename_c.split(' ')
    if filec == 'put':
        file_path = os.path.join(((sys.path)[-1]), "user_root")
        f_path = os.path.join(file_path, user)
        filename = os.path.join(f_path, filename)
        if os.path.isfile(filename) is False:
            syn = "ready"
            self.request.sendall(syn.encode())
            f = open(filename, 'wb')
            while True:
                data = self.request.recv(102400)
                if data == b'EOF':
                    break
                if not data:
                    break
                f.write(data)
            f.close()
            time.sleep(1)
            print(" {} : {} {} 传输成功".format(time.ctime(), user,filename_c))
        else:
            self.request.sendall("False".encode())
            print(" {} : {} {} 传输失败".format(time.ctime(), user, filename_c))
    elif filec == 'get':
        file_path = os.path.join(((sys.path)[-1]), "user_root")
        f_path = os.path.join(file_path, user)
        filename = os.path.join(f_path, filename)
        if os.path.isfile(filename) is True:
            syn = "ready"
            self.request.sendall(syn.encode())
            f = open(filename, 'rb')
            while True:
                data = f.read(102400)
                if not data:
                    break
                self.request.sendall(data)
            f.close()
            time.sleep(1)
            self.request.sendall('EOF'.encode())
            print(" {} : {} {} 传输成功".format(time.ctime(), user, filename_c))
        else:
            self.request.sendall("False".encode())
            print(" {} : {} {} 传输失败".format(time.ctime(), user, filename_c))
    else:
        errmsg = ("格式错误!")
        self.request.sendall(errmsg.encode())
        print(" {} : {} {}".format(time.ctime(), user, errmsg))
        pass
    

      



    `client`展示:

    ------- 文件操作 ---------

    支持任何文件格式 gz zip mp4 txt
    1. 上传文件 {eq: put filename}
    2. 下载文件 {eq: get filename}
    3. 退出 {eq: quit}
    4. 暂时不支持覆盖文件

    abu #get bible.txt
    recv file success!
    abu #quit
    =-=-=-=-=-=-=-=-=-=-=-=-=-=退出模块=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    ------- abu个人空间 ---------

    1. 传输文件
    2. 命令交互
    3. 退出

    请选择:2

    ------- 命令行模式 ---------

    1. 当前用户根目录
    2. 支持常用命令{eq: ls }
    3. 退出 quit

    Sent: dir
    Received: 驱动器 F 中的卷是 生活
    卷的序列号是 1C94-79CB

    F:mologa-workspaceweek_5week-5ftp_suser_rootabu 的目录

    2018/01/29 14:21 <DIR> .
    2018/01/29 14:21 <DIR> ..
    2018/01/29 14:21 4,672,137 bible.txt
    1 个文件 4,672,137 字节
    2 个目录 298,844,844,032 可用字节

    Sent: quit
    =-=-=-=-=-=-=-=-=-=-=-=-=-=退出模块=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    `server`log展示:

    127.0.0.1 request
    Mon Jan 29 16:06:13 2018 : abu 认证成功
    127.0.0.1 request
    Mon Jan 29 16:06:24 2018 : abu get bible.txt 传输成功
    127.0.0.1 request
    Mon Jan 29 16:06:34 2018 : abu 执行 dir


    3)编码转换

    def run_command(self,com):
        root_path = (file_path + os.sep + self.user)
        res = subprocess.run("%s" % com, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,cwd=root_path)
        if platform.system() == "Windows":
            code = 'gbk'
        else:
            code = 'utf-8'
        if res.returncode is 0:
            ack = (res.stdout).decode(code)
        else:
            ack = (res.stderr).decode(code)
        return ack
    

      




    总结备注

    ```
    坚持学习真的很重要;
    学习:
    1.str,byte,gbk编码的转换和了解
    2.学习了socket的端口工作原理
    3.多样化数据格式定义与统一化
    file:
    file_(put file)
    file_(get file)
    command:
    com_(command)
    auth:
    auth_('user','password')
    |__login、register、auth


    register_{'abc': '900150983cd24fb0d6963f7d28e17f72'}
    client:
    new_member = (user,md5_value)
    new_member = str(new_member)
    new_member = "register_"+new_member
    将字典转换成元组,到server端之后统一切分之后再转换回字典
    server:
    key = eval(args)[0]
    value = eval(args)[1]
    args = {key:value}
    auth_('miao', '1058a42a81e5252c76cb308bcd6a0214')
    com_('miao', 'dir')
    file_('miao', 'bible.txt')

    通过:mode, args = msg.split('_')
    分别选择模式-->执行args

    ```

  • 相关阅读:
    损失函数绘图
    nexus+maven配置
    tomcat 修改端口号
    Git 删除远程仓库文件,文件夹
    git 删除远程分支 branch
    IBM WebSphere Commerce之订单处理
    Python+Selenium自动化
    git push 时 rejected
    IBM WebSphere Commerce初探
    NetApp存储
  • 原文地址:https://www.cnblogs.com/mologa-jie/p/8378070.html
Copyright © 2011-2022 走看看