之前用单用户ftp
上传,服务器同时只能处理一个客户端的连接,要做到多客户端连接可以直接使用python
帮我们封装好的socketserver
模块。以下代码为多用户ftp
上传示例,里面用到md5
文件一致性校验,在一个win
机器上同时扮演客户端和服务器没问题,但是当有一方使用了linux
就出现问题了。运行代码测试发现;同样的文件内容,在win
和linux
是进行md5
加密内容发现执行的结果不一样。没测试在两台win
上是否一样,有其他人看到可以自己测试下。
服务器端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import socketserver import struct import pickle import os import hashlib ip_port = ('10.10.10.103', 9999) md5 = hashlib.md5(b'tony')
class FtpServer(socketserver.BaseRequestHandler): def handle(self): print(self.client_address, '已成功连接至服务器……') while 1: try: file_info_len_struct = self.request.recv(4) if file_info_len_struct == '': break file_info_len = struct.unpack('i', file_info_len_struct)[0] file_info_pickle = self.request.recv(file_info_len) file_info = pickle.loads(file_info_pickle) file_path = file_info['file_path'] file_size = file_info['file_size'] file_name = os.path.basename(file_path) with open('up/'+file_name, 'wb') as f: receive_lenth = 0 while receive_lenth < file_size: data = self.request.recv(1024) md5.update(data) receive_lenth += len(data) f.write(data) print('文件总大小:{}, 已接收:{}, 已接收百分比{:.2f}%'.format(file_size, receive_lenth, receive_lenth/file_size*100)) print(file_name+'文件上传成功') print(md5.hexdigest()) self.request.send(md5.hexdigest().encode('utf8')) except Exception as e: print(e) break print(self.client_address, '已断开连接……') self.request.close()
ftp = socketserver.ThreadingTCPServer(ip_port, FtpServer) ftp.serve_forever()
|
客户端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import socket import os import pickle import struct import hashlib md5 = hashlib.md5(b'tony') ip_port = ('10.10.10.103', 9999) client = socket.socket()
client.connect(ip_port) while 1: file = input('请选择您要上传的文件:') if file == '' or file == 'exit' or not os.path.exists(file): break file_dic = { 'file_path' : file, 'file_size' : os.path.getsize(file) } file_dic_pickle = pickle.dumps(file_dic) file_dic_pickle_len = len(file_dic_pickle) file_dic_pickle_len_struct = struct.pack('i', file_dic_pickle_len) client.send(file_dic_pickle_len_struct) client.send(file_dic_pickle) with open(file, 'rb') as f: for line in f: md5.update(line) client.send(line) ret = client.recv(1024).decode('utf8') print(ret) print(md5.hexdigest()) if ret == md5.hexdigest(): print('文件上传校验成功') else: print('文件上传校验失败')
client.close()
|