服务器端程序
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()