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.')
posted @ 2020-07-30 18:30  Raigor  阅读(155)  评论(0编辑  收藏  举报