初级版python登录验证,上传下载文件加MD5文件校验

服务器端程序

import socket
import json
import struct
import hashlib
import os


def md5_code(usr, pwd):
    ret = hashlib.md5(usr.encode())
    ret.update(pwd.encode())
    return ret.hexdigest()


def login():
    recv_msg = conn.recv(1024).decode()
    msg_dic = json.loads(recv_msg)
    with open('user_msg', 'r', encoding='utf-8') as f1, \
            open('user_msg', 'a', encoding='utf-8') as f2:
        for con in f1:
            con_li = con.strip().split()
            if con_li[0] == msg_dic['username'] and con_li[1] == md5_code(msg_dic['username'], msg_dic['password']):
                flag = json.dumps({'flag': 1})
                conn.send(flag.encode())
                return {'flag': 1}
        else:
            flag = json.dumps({'flag': 0})
            conn.send(flag.encode())
            content = msg_dic['username'] + '\t' + md5_code(msg_dic['username'], msg_dic['password']) + '\n'
            f2.write(content)
            return {'flag': 0}


def upload():
    dic_len = conn.recv(4)
    dic_size = struct.unpack('i', dic_len)[0]
    file_info = json.loads(conn.recv(dic_size))
    f1 = open(file_info['filename'], 'wb')
    md5_data = hashlib.md5()

    while file_info['filesize'] > 0:
        # 在最后接收文件不足2048时接收精准字节,避免与后面发送的数据发生粘包
        if 0 < file_info['filesize'] < 1204:
            content = conn.recv(file_info['filesize'])
        else:
            content = conn.recv(2048)
        md5_data.update(content)
        f1.write(content)
        # 每次减去实际接收的文件长度可以避免tcp协议拆包时实际接收到的数据没有2048而导致接收数据不完整
        file_info['filesize'] -= len(content)

    f1.close()

    # 获得校验后的md5值
    md5sum = md5_data.hexdigest()
    # 接收客户端校验后的md5值
    recv_md5 = conn.recv(32).decode()

    if md5sum == recv_md5:
        print('校验成功')
        return {'flag': 1}
    else:
        print('校验失败')
        return {'flag': 0}


def download():
    dic_len = conn.recv(4)
    dic_size = struct.unpack('i', dic_len)[0]
    file_info = json.loads(conn.recv(dic_size))
    file_size = os.path.getsize(file_info['filename'])

    dir_list = os.listdir('.')
    dfile_info = {'filesize': file_size, 'operate': 'download', 'dir_list': dir_list}
    file_dic = json.dumps(dfile_info).encode()
    file_len = struct.pack('i', len(file_dic))

    # 发送文件信息
    conn.send(file_len)
    conn.send(file_dic)

    f1 = open(file_info['filename'], 'rb')
    md5_data = hashlib.md5()

    while file_size:
        content = f1.read(2048)
        md5_data.update(content)
        file_size -= len(content)
        conn.send(content)
    f1.close()

    md5sum = md5_data.hexdigest()
    print(md5sum)
    conn.send(md5sum.encode())
    return {'flag': 1}


server = socket.socket()
server.bind(('127.0.0.1', 8001))
server.listen(5)
conn, addr = server.accept()

login_ret = login()
if login_ret['flag']:
    while login_ret['flag']:
        recv_cmd = conn.recv(1024).decode()
        cmd_dic = json.loads(recv_cmd)
        if cmd_dic['cmd'] == '1':
            print('上传文件中')
            upload()
        elif cmd_dic['cmd'] == '2':
            print('下载文件中')
            download()
        elif cmd_dic['cmd'] == '3':
            break
else:
    print('请重新登录')


conn.close()
server.close()

客户端程序

import os
import json
import socket
import struct
import hashlib
# import time


def login():
    usr = input('请输入用户名:')
    pwd = input('请输入密码:')
    usr_info_dic = {'username': usr, 'password': pwd, 'operate': 'login'}
    usr_info = json.dumps(usr_info_dic).encode()
    client.send(usr_info)
    ret = client.recv(1024).decode()
    flag_dic = json.loads(ret)
    if flag_dic['flag']:
        print('登录成功')
        return {'flag': 1}
    else:
        print('登录失败')
        return {'flag': 0}


def upload():
    # F:\test.mp4
    file_path = input('请输入文件路径:')
    file_size = os.path.getsize(file_path)
    file_name = os.path.basename(file_path)
    file_info = {'filesize': file_size, 'filename': file_name, 'operate': 'upload'}
    file_dic = json.dumps(file_info).encode()
    file_len = struct.pack('i', len(file_dic))
    # 发送文件信息
    client.send(file_len)
    client.send(file_dic)

    total_size = file_size
    # 打开文件准备上传文件
    md5_data = hashlib.md5()

    f1 = open(file_path, 'rb')
    while file_size:
        content = f1.read(2048*10)
        md5_data.update(content)
        file_size -= len(content)
        client.send(content)
        print('\r已上传%s%%' % int((1 - file_size / total_size) * 100), end='')
    print('上传成功!')
    f1.close()

    md5sum = md5_data.hexdigest()
    print(md5sum)
    # time.sleep(0.1)
    client.send(md5sum.encode())

    return {'flag': 1}


def download():
    # F:\test.mp4
    file_name = input('请输入文件名:')
    file_info = {'filename': file_name, 'operate': 'download'}
    file_dic = json.dumps(file_info).encode()
    file_len = struct.pack('i', len(file_dic))
    # # 发送文件信息
    client.send(file_len)
    client.send(file_dic)

    dic_len = client.recv(4)
    dic_size = struct.unpack('i', dic_len)[0]
    dfile_info = json.loads(client.recv(dic_size))

    md5_data = hashlib.md5()
    for dir_index, dir_name in enumerate(dfile_info['dir_list']):
        print(dir_index, dir_name)

    total_size = dfile_info['filesize']
    f1 = open('down' + file_name, 'wb')
    while dfile_info['filesize'] > 0:
        # 在最后接收文件不足2048时接收精准字节,避免与后面发送的数据发生粘包
        if 0 < dfile_info['filesize'] < 1204:
            content = client.recv(dfile_info['filesize'])
        else:
            content = client.recv(2048)
        md5_data.update(content)
        f1.write(content)
        dfile_info['filesize'] -= len(content)
        print('\r已下载%s%%' % int((1-dfile_info['filesize'] / total_size) * 100), end='')
    f1.close()

    md5sum = md5_data.hexdigest()
    # print('\n', md5sum)

    recv_md5 = client.recv(32).decode()

    # print(recv_md5)
    if md5sum == recv_md5:
        print('校验成功')
        return {'flag': 1}
    else:
        print('校验失败')
        return {'flag': 0}
    # print('下载成功!')
    # return {'flag': 1}


def choose_cmd():
    print('''
    1.上传文件
    2.下载文件
    3.退出上传下载文件
    ''')
    cmd = input('请输入序号选择相应操作')
    dic = {'cmd': cmd}
    cmd_dic = json.dumps(dic).encode()
    client.send(cmd_dic)
    return dic


client = socket.socket()
# client.connect(('192.168.13.13', 8001))
client.connect(('127.0.0.1', 8001))

login_ret = login()
if login_ret['flag']:
    while login_ret['flag']:
        cmd_ret = choose_cmd()
        if cmd_ret['cmd'] == '1':
            upload()
        elif cmd_ret['cmd'] == '2':
            download()
        elif cmd_ret['cmd'] == '3':
            break
        else:
            print('输入的序号有误')
else:
    print('请重新登录')


client.close()

猜你喜欢

转载自www.cnblogs.com/chen55555/p/10318267.html