server------------
#!/usr/bin/env python # encoding: utf-8 # Date: 2018/6/7import socketimport osimport jsonimport structshar_dir = r'E:\python\PycharmProjects\python.base.demo\model3\socket1\上传下载\优化版本\server\share'def put(conn, cmds): obj = conn.recv(4) header_size = struct.unpack('i', obj)[0] # 2.2收报头 header_bytes = conn.recv(header_size) # 从报头中解析出对真实数据的描述信息 header_json = header_bytes.decode('utf-8') header_dic = json.loads(header_json) print(header_dic) total_size = header_dic['file_size'] filename = header_dic['filename'] # 2.4,接收真实的数据 with open('%s/%s' % (shar_dir, filename), 'wb') as f: # 服务端打开读方式,这里这种wb方式容易卡主 recv_size = 0 while recv_size < total_size: line = conn.recv(1024) f.write(line) recv_size += len(line) print('总大小:%s 已上传大小: %s' % (total_size, recv_size))def get(conn, cmds): filename = cmds[1] # 3,易读的方式打开文件,读取文件内容发送给客户端 header_dic = { 'filename': filename, 'md5': 'xxxdxxx', 'file_size': os.path.getsize(r'%s/%s' % (shar_dir, filename)) } header_json = json.dumps(header_dic) header_bytes = header_json.encode('utf-8') # 2,先发送报头的长度 conn.send(struct.pack('i', len(header_bytes))) # 3,再发报头 conn.send(header_bytes) # 4,再发送真实的数据 with open('%s/%s' % (shar_dir, filename), 'rb') as f: # conn.send(f.read()) for line in f: conn.send(line)def run(): phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.bind(('127.0.0.1', 9909)) phone.listen(5) print('starting...') while True: conn, client_addr = phone.accept() print(client_addr) while True: try: # 1收命令 res = conn.recv(8096) # b'get a.txt' if not res:break # 2,解析命令,提取相应命令参数 cmds = res.decode('utf-8').split() # ['get',filename] if cmds[0] == 'get': get(conn, cmds) elif cmds[0] == 'put': put(conn, cmds) except ConnectionResetError: break conn.close() phone.close()if __name__ == '__main__': run()client--------------------#!/usr/bin/env python # encoding: utf-8 # Date: 2018/6/7import socketimport structimport jsonimport osdow_dir = r'E:\python\PycharmProjects\python.base.demo\model3\socket1\上传下载\优化版本\client\download'def put(phone, cmds): filename = cmds[1] # 3,易读的方式打开文件,读取文件内容发送给客户端 header_dic = { 'filename': filename, 'md5': 'xxxdxxx', 'file_size': os.path.getsize(r'%s/%s' % (dow_dir, filename)) } header_json = json.dumps(header_dic) header_bytes = header_json.encode('utf-8') # 2,先发送报头的长度 phone.send(struct.pack('i', len(header_bytes))) # 3,再发报头 phone.send(header_bytes) # 4,再发送真实的数据 with open('%s/%s' % (dow_dir, filename), 'rb') as f: # conn.send(f.read()) for line in f: phone.send(line)def get(phone, cmds): # 2,以写的方式打开一个新文件 # 2.1收报头长度 obj = phone.recv(4) header_size = struct.unpack('i', obj)[0] # 2.2收报头 header_bytes = phone.recv(header_size) # 从报头中解析出对真实数据的描述信息 header_json = header_bytes.decode('utf-8') header_dic = json.loads(header_json) print(header_dic) total_size = header_dic['file_size'] filename = header_dic['filename'] # 2.4,接收真实的数据 with open('%s/%s' % (dow_dir, filename), 'wb') as f: # 服务端打开读方式,这里这种wb方式容易卡主 recv_size = 0 while recv_size < total_size: line = phone.recv(1024) f.write(line) recv_size += len(line) print('总大小:%s 已下载大小: %s' % (total_size, recv_size))def run(): phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.connect(('127.0.0.1', 9909)) while True: # 1,发命令 cmd = input('>>:').strip() if not cmd:continue phone.send(cmd.encode('utf-8')) cmds = cmd.split() if cmds[0] == 'get': get(phone, cmds) elif cmds[0] == 'put': put(phone, cmds) phone.close()if __name__ == '__main__': run()