zoukankan      html  css  js  c++  java
  • 29 练习:利用socketserver实现TCP协议下登录认证下载

    题目要求:
    # 1.登录 + 文件下载
    # 用户必须登录才能下载
    # 用户是否登录应该记录在服务器
    # 并且用户可以自己选择 上传 还是 下载
    
    # server.py
    
    import socketserver
    import struct
    import json
    import os
    
    BASE_PATH = os.path.dirname(__file__)
    REGISTER_PATH = 'register'
    Login_User = None
    User_path = ''
    
    
    class Myserver(socketserver.BaseRequestHandler):
        def handle(self):
            conn = self.request
            for i in range(3):
                b_length = conn.recv(4)
                length = struct.unpack('i', b_length)[0]
                s_dic = conn.recv(length).decode('utf-8')
                login_dic = json.loads(s_dic)
                with open(REGISTER_PATH, encoding='utf-8', mode='rt') as file_handler:
                    for line in file_handler:
                        username, password = line.strip().split('|')
                        if login_dic['username'] == username and login_dic['password'] == password:
                            conn.send('login success.'.encode('utf-8'))
                            global Login_User
                            Login_User = login_dic['username']
                            if not os.path.isdir(os.path.join(BASE_PATH, Login_User)):
                                os.mkdir(os.path.join(BASE_PATH, Login_User))
                            User_path = os.path.join(BASE_PATH, Login_User)
                            break
                if Login_User is None:
                    conn.send('login failed.'.encode('utf-8'))
            if Login_User:
                while True:
                    mode = conn.recv(1).decode('utf-8')
                    if mode == '1':  # 上传
                        b_length = conn.recv(4)
                        length = struct.unpack('i', b_length)[0]
                        b_file_dic = conn.recv(length)
                        file_dic = json.loads(b_file_dic)
                        with open(os.path.join(User_path, file_dic['filename']), mode='wb') as file_handler:
                            while file_dic['filesize'] > 0:
                                content = conn.recv(1024)
                                file_dic['filesize'] -= len(content)
                                file_handler.write(content)
                        if file_dic['filesize'] == 0:
                            conn.send('True'.encode('utf-8'))
                        else: conn.send('False'.encode('utf-8'))
                    if mode == '2': # 下载
                        obj = os.walk(User_path)
                        _, _, file_list = obj.__next__()
                        # print(file_list)
                        s_file_list = json.dumps(file_list)
                        b_length = struct.pack('i', len(s_file_list))
                        conn.send(b_length)
                        conn.send(s_file_list.encode('utf-8'))
                        b_length = conn.recv(4)
                        length = struct.unpack('i', b_length)[0]
                        filename = conn.recv(length).decode('utf-8')
                        filesize = os.path.getsize(os.path.join(User_path, filename))
                        file_dic = {'filename': filename, 'filesize': filesize}
                        b_file_dic = json.dumps(file_dic).encode('utf-8')
                        b_length = struct.pack('i', len(b_file_dic))
                        conn.send(b_length)
                        conn.send(b_file_dic)
                        with open(os.path.join(User_path, file_dic['filename']), mode='rb') as file_handler:
                            while file_dic['filesize'] > 0:
                                content = file_handler.read(1024)
                                file_dic['filesize'] -= len(content)
                                conn.send(content)
                    if mode == '3':
                        conn.close()
                        break
    
    
    
    
    server = socketserver.ThreadingTCPServer(('127.0.0.1', 9000), Myserver)
    server.serve_forever()
    
    
    # client.py
    
    import socket
    import struct
    import json
    import os
    
    BASE_PATH = os.path.dirname(__file__)
    User = None
    User_path = ''
    
    sk = socket.socket()
    sk.connect(('127.0.0.1', 9000))
    
    for i in range(3):
        username = input('username>>>')
        password = input('password>>>')
        login_dic = {'username': username, 'password': password}
        s_dic = json.dumps(login_dic)
        b_length = struct.pack('i', len(s_dic))
        sk.send(b_length)
        sk.send(s_dic.encode('utf-8'))
        ret = sk.recv(1024).decode('utf-8')
        print(ret)
        if ret == 'login success.':
            User = username
            User_path = os.path.join(BASE_PATH, User)
            if not os.path.isdir(User_path):
                os.mkdir(User_path)
            break
    if User:
        while True:
            print('1.上传文件')
            print('2.下载文件')
            print('3.退出程序')
            mode = input('PLS select ur mode.>>>')
            if mode.isdecimal():
                if mode == '1':
                    sk.send(mode.encode('utf-8'))
                    while True:
                        path = input('Pls input ur absolute path.>>>')
                        if os.path.isfile(path):
                            filename = os.path.basename(path)
                            filesize = os.path.getsize(path)
                            file_dic = {'filename': filename, 'filesize': filesize}
                            s_dic = json.dumps(file_dic)
                            b_length = struct.pack('i', len(s_dic))
                            sk.send(b_length)
                            sk.send(s_dic.encode('utf-8'))
                            with open(path, mode='rb') as file_handler:
                                while file_dic['filesize'] > 0:
                                    content = file_handler.read(1024)
                                    file_dic['filesize'] -= len(content)
                                    sk.send(content)
                            print(sk.recv(1024).decode('utf-8'))
                            break
                elif mode == '2':
                    sk.send(mode.encode('utf-8'))
                    b_length = sk.recv(4)
                    length = struct.unpack('i', b_length)[0]
                    s_file_list = sk.recv(length).decode('utf-8')
                    file_list = json.loads(s_file_list)
                    for num, filename in enumerate(file_list, 1):
                        print(num, filename)
                    b_download_filename = input('Pls input ur download filename.>>>').encode('utf-8')
                    b_length = struct.pack('i', len(b_download_filename))
                    sk.send(b_length)
                    sk.send(b_download_filename)
                    b_length = sk.recv(4)
                    length = struct.unpack('i', b_length)[0]
                    s_file_dic = sk.recv(length).decode('utf-8')
                    file_dic = json.loads(s_file_dic)
                    with open(os.path.join(User_path, file_dic['filename']), mode='wb') as file_handler:
                        while file_dic['filesize'] > 0:
                            content = sk.recv(1024)
                            file_dic['filesize'] -= len(content)
                            file_handler.write(content)
                        if file_dic['filesize'] == 0:
                            print('Download success.')
                elif mode == '3':
                    sk.send(mode.encode('utf-8'))
                    sk.close()
                    break
                else:
                    print('Illegal input.')
            else: print('Illegal input.')
    
  • 相关阅读:
    关于ASP.NET MVC的业务逻辑验证(validation)
    AJAX的跨域与JSONP(另送一个为文章自动添加短址的功能)
    oXite源码学习导读二:Action的返回类型与IActionInvoker
    访问需要HTTP Basic Authentication认证的资源的各种语言的实现
    ASP.NET MVC 1.0 发布了
    简单学习下Oxite的项目结构2
    制作Visual Studio项目模板
    LumaQQ.NET For Visual Studio 2005
    深入ASP.NET数据绑定(下)——多样的绑定方式
    深入ASP.NET数据绑定(上)
  • 原文地址:https://www.cnblogs.com/raygor/p/13405611.html
Copyright © 2011-2022 走看看