标签:网络编程 eve use symbol 数据 serve ... [1] ack
server端:
import socket import struct import json import os share_dir = r‘C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\server\share‘ IP_PORT = (‘127.0.0.1‘, 8999) def bytes2human(n): symbols = (‘K‘, ‘M‘, ‘G‘, ‘T‘, ‘P‘, ‘E‘) prefix = {} for i, s in enumerate(symbols): # << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4, # 10位就表示1024 即1 << 10=1024 就是2的n次方 prefix[s] = 1 << (i + 1) * 10 for s in reversed(symbols): if n >= prefix[s]: value = float(n) / prefix[s] return ‘%.2f%s‘ % (value, s) return "%sB" % n def get(conn,file_name): # 3、以读的方式打开文件,读取文件内容发送给客户端 # 第一步:制作固定长度的报头 print(‘get‘) try: header_dict = { ‘file_name‘: file_name, ‘md5‘: ‘xxx‘, ‘file_size‘: os.path.getsize(os.path.join(share_dir, file_name)) } header_json = json.dumps(header_dict, ensure_ascii=‘False‘, indent=2) header_bytes = header_json.encode(‘utf-8‘) # 第二步:先发送报头的长度 conn.send(struct.pack(‘i‘, len(header_bytes))) # 第三步:再发报头 conn.send(header_bytes) # 第四步:再发送真实的数据 with open(os.path.join(share_dir, file_name), ‘rb‘) as f: for line in f: conn.send(line) except Exception as e: print(e) def put(conn, file_name): """ 接收客户端上传文件 :param conn: :param file_name: :return: """ # 2、以写的方式打开一个新文件,接收客户端发来的文件的内容写入服务端新文件 # 第一步:先收报头的长度 header_len = conn.recv(4) header_size = struct.unpack(‘i‘, header_len)[0] # 第二步:再收报头 header_json = conn.recv(header_size).decode(‘utf-8‘) # 第三步:从报头中解析出对真实数据的描述信息 header_dict = json.loads(header_json) file_size = header_dict[‘file_size‘] file_name = header_dict[‘file_name‘] print(os.path.join(share_dir, file_name)) # 第四步:接收真实的数据,写入文件 with open(os.path.join(share_dir, file_name), ‘wb‘) as f: recv_size = 0 while recv_size < file_size: line = conn.recv(1024) f.write(line) recv_size += len(line) print(‘总大小:%s 已上传大小:%s‘ % (bytes2human(file_size), bytes2human(recv_size))) def run(): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(IP_PORT) server.listen(5) print(‘starting...‘) while True: conn, addr = server.accept() print(addr) while True: try: # 1 收命令 res = conn.recv(1024) # b‘ get a.txt‘ if not res:break # 2、解析命令,提取相应命令参数 cmds = res.decode(‘utf-8‘).split() # [get, a.txt] if cmds[0] == ‘get‘: get(conn, cmds[1]) # 下载文件 # file_name = cmds[1] elif cmds[0] == ‘put‘: put(conn, cmds[1]) # 上传文件 except ConnectionResetError: #适用于windows操作系统 break conn.close() server.close() if __name__ == ‘__main__‘: run()
client端
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import socket import struct import json import os share_dir = r‘C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\client\download‘ IP_PORT = (‘127.0.0.1‘, 8999) def bytes2human(n): symbols = (‘K‘, ‘M‘, ‘G‘, ‘T‘, ‘P‘, ‘E‘) prefix = {} for i, s in enumerate(symbols): # << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4, # 10位就表示1024 即1 << 10=1024 就是2的n次方 prefix[s] = 1 << (i + 1) * 10 for s in reversed(symbols): if n >= prefix[s]: value = float(n) / prefix[s] return ‘%.2f%s‘ % (value, s) return "%sB" % n def get(client, file_name): # 2、以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户的新文件 # 第一步:先收报头的长度 header_len = client.recv(4) header_size = struct.unpack(‘i‘, header_len)[0] # 第二步:再收报头 header_json = client.recv(header_size).decode(‘utf-8‘) # 第三步:从报头中解析出对真实数据的描述信息 header_dict = json.loads(header_json) file_size = header_dict[‘file_size‘] file_name = header_dict[‘file_name‘] print(os.path.join(share_dir, file_name)) # 第四步:接收真实的数据,写入文件 with open(os.path.join(share_dir, file_name), ‘wb‘) as f: recv_size = 0 while recv_size < file_size: line = client.recv(1024) f.write(line) recv_size += len(line) print(‘总大小:%s 已下载大小:%s‘ % (bytes2human(file_size), bytes2human(recv_size))) def put(client, file_name): # 向服务端上传文件 print(‘put‘) try: if not os.path.isfile(os.path.join(share_dir, file_name)): print(‘file:%s is not exists‘ % os.path.join(share_dir, file_name)) return else: file_size = os.path.getsize(os.path.join(share_dir, file_name)) header_dict = { ‘file_name‘: file_name, ‘md5‘: ‘xxx‘, ‘file_size‘: file_size } header_json = json.dumps(header_dict, ensure_ascii=‘False‘, indent=2) header_bytes = header_json.encode(‘utf-8‘) # 第二步:先发送报头的长度 client.send(struct.pack(‘i‘, len(header_bytes))) # 第三步:再发报头 client.send(header_bytes) # 第四步:再发送真实的数据 with open(os.path.join(share_dir, file_name), ‘rb‘) as f: for line in f: client.send(line) except Exception as e: print(e) def run(): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(IP_PORT) while True: # 1、发命令 cmd = input(‘>> ‘).strip() # ‘get a.txt‘ if not cmd:continue client.send(cmd.encode(‘utf-8‘)) if cmd.startswith(‘get‘): get(client, cmd.split()[1]) elif cmd.startswith(‘put‘): put(client, cmd.split()[1]) client.close() if __name__ == ‘__main__‘: run()
输出结果
sever: starting... (‘127.0.0.1‘, 19074) get get C:\Users\jingjing\PycharmProjects\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\server\share\3.jpeg 总大小:75.36K 已上传大小:1.00K 总大小:75.36K 已上传大小:2.00K …… 总大小:75.36K 已上传大小:75.36K client: >> get 1.pptx C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\client\download\1.pptx 总大小:970.93K 已下载大小:1.00K 总大小:970.93K 已下载大小:2.00K …… 总大小:970.93K 已下载大小:970.93K >> put 3.jpeg put >>
server端:
import socket import struct import json import os class TCPServer: IP_PORT = (‘127.0.0.1‘, 8999) request_queue_size = 5 allow_reuse_address = False max_packet_size = 8192 share_dir = r‘C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\server\share‘ def __init__(self, address=IP_PORT, bind_and_activate=True): self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if bind_and_activate: try: self.server.bind(address) self.server.listen(self.request_queue_size) print(‘starting...‘) except Exception as e: self.server.close() raise e def get_request(self): """Get the request and client address from the socket. """ return self.server.accept() def run(self): while True: self.conn, self.client_addr = self.get_request() print(‘from client ‘, self.client_addr) while True: try: # 1 收命令 res = self.conn.recv(self.max_packet_size) # b‘ get a.txt‘ if not res: break # 2、解析命令,提取相应命令参数 cmds = res.decode(‘utf-8‘).split() # [get, a.txt] if hasattr(self, cmds[0]): func = getattr(self, cmds[0]) func(cmds[1]) except ConnectionResetError: # 适用于windows操作系统 break self.conn.close() self.server.close() def put(self, file_name): """ 接收客户端上传文件 :param conn: :param file_name: :return: """ print(‘get file %s‘ % file_name) # 2、以写的方式打开一个新文件,接收客户端发来的文件的内容写入服务端新文件 # 第一步:先收报头的长度 header_len = self.conn.recv(4) header_size = struct.unpack(‘i‘, header_len)[0] # 第二步:再收报头 header_json = self.conn.recv(header_size).decode(‘utf-8‘) # 第三步:从报头中解析出对真实数据的描述信息 header_dict = json.loads(header_json) file_size = header_dict[‘file_size‘] file_name = header_dict[‘file_name‘] print(os.path.join(self.share_dir, file_name)) # 第四步:接收真实的数据,写入文件 with open(os.path.join(self.share_dir, file_name), ‘wb‘) as f: recv_size = 0 while recv_size < file_size: line = self.conn.recv(self.max_packet_size) f.write(line) recv_size += len(line) rate = recv_size / file_size * 100 print(‘总大小:%s 已上传:%%%.2f‘ % (self.bytes2human(file_size), rate)) @staticmethod def bytes2human(n): symbols = (‘K‘, ‘M‘, ‘G‘, ‘T‘, ‘P‘, ‘E‘) prefix = {} for i, s in enumerate(symbols): # << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4, # 10位就表示1024 即1 << 10=1024 就是2的n次方 prefix[s] = 1 << (i + 1) * 10 for s in reversed(symbols): if n >= prefix[s]: value = float(n) / prefix[s] return ‘%.2f%s‘ % (value, s) return "%sB" % n def get(self, file_name): # 3、以读的方式打开文件,读取文件内容发送给客户端 # 第一步:制作固定长度的报头 print(‘send file %s‘ % file_name) try: header_dict = { ‘file_name‘: file_name, ‘md5‘: ‘xxx‘, ‘file_size‘: os.path.getsize(os.path.join(self.share_dir, file_name)) } header_json = json.dumps(header_dict, ensure_ascii=‘False‘, indent=2) header_bytes = header_json.encode(‘utf-8‘) # 第二步:先发送报头的长度 self.conn.send(struct.pack(‘i‘, len(header_bytes))) # 第三步:再发报头 self.conn.send(header_bytes) # 第四步:再发送真实的数据 with open(os.path.join(self.share_dir, file_name), ‘rb‘) as f: for line in f: self.conn.send(line) except Exception as e: print(e) if __name__ == ‘__main__‘: s = TCPServer() s.run()
client端:
import socket import struct import json import os class TCPClient: IP_PORT = (‘127.0.0.1‘, 8999) request_queue_size = 5 allow_reuse_address = False max_packet_size = 8192 share_dir = r‘C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\client\download‘ def __init__(self, address=IP_PORT, connect=True): self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if connect: try: self.client.connect(address) except Exception as e: self.client.close() raise e def run(self): while True: # 1、发命令 inp = input(‘>> ‘).strip() # ‘get a.txt‘ if not inp: continue self.client.send(inp.encode(‘utf-8‘)) cmd = inp.split() if hasattr(self, cmd[0]): func = getattr(self, cmd[0]) func(cmd[1]) client.close() @staticmethod def bytes2human(n): symbols = (‘K‘, ‘M‘, ‘G‘, ‘T‘, ‘P‘, ‘E‘) prefix = {} for i, s in enumerate(symbols): # << 左移” 左移一位表示乘2 即1 << 1=2,二位就表示4 即1 << 2=4, # 10位就表示1024 即1 << 10=1024 就是2的n次方 prefix[s] = 1 << (i + 1) * 10 for s in reversed(symbols): if n >= prefix[s]: value = float(n) / prefix[s] return ‘%.2f%s‘ % (value, s) return "%sB" % n def get(self, file_name): # 2、以写的方式打开一个新文件,接收服务端发来的文件的内容写入客户的新文件 # 第一步:先收报头的长度 header_len = self.client.recv(4) header_size = struct.unpack(‘i‘, header_len)[0] # 第二步:再收报头 header_json = self.client.recv(header_size).decode(‘utf-8‘) # 第三步:从报头中解析出对真实数据的描述信息 header_dict = json.loads(header_json) file_size = header_dict[‘file_size‘] file_name = header_dict[‘file_name‘] print(os.path.join(self.share_dir, file_name)) # 第四步:接收真实的数据,写入文件 with open(os.path.join(self.share_dir, file_name), ‘wb‘) as f: recv_size = 0 while recv_size < file_size: line = self.client.recv(self.max_packet_size) f.write(line) recv_size += len(line) rate = recv_size / file_size * 100 print(‘总大小:%s 已下载:%%%.2f‘ % (self.bytes2human(file_size),rate)) def put(self, file_name): # 向服务端上传文件 print(‘put‘) try: if not os.path.isfile(os.path.join(self.share_dir, file_name)): print(‘file:%s is not exists‘ % os.path.join(self.share_dir, file_name)) return else: file_size = os.path.getsize(os.path.join(self.share_dir, file_name)) header_dict = { ‘file_name‘: file_name, ‘md5‘: ‘xxx‘, ‘file_size‘: file_size } header_json = json.dumps(header_dict, ensure_ascii=‘False‘, indent=2) header_bytes = header_json.encode(‘utf-8‘) # 第二步:先发送报头的长度 self.client.send(struct.pack(‘i‘, len(header_bytes))) # 第三步:再发报头 self.client.send(header_bytes) # 第四步:再发送真实的数据 with open(os.path.join(self.share_dir, file_name), ‘rb‘) as f: for line in f: self.client.send(line) except Exception as e: print(e) if __name__ == ‘__main__‘: c = TCPClient() c.run()
输出结果:
sever: starting... from client (‘127.0.0.1‘, 3500) send file 3.jpeg get file 1.pptx C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\server\share\1.pptx 总大小:970.93K 已上传:%0.82 …… 总大小:970.93K 已上传:%99.96 总大小:970.93K 已上传:%100.00 client: C:/py3Project/路飞/第三模块/第二章网络编程/05_文件传输/简单版本/client/file_client.py >> get 3.jpeg C:\py3Project\路飞\第三模块\第二章网络编程\05_文件传输\简单版本\client\download\3.jpeg 总大小:75.36K 已下载:%10.62 …… 总大小:75.36K 已下载:%99.49 总大小:75.36K 已下载:%100.00 >> put 1.pptx put >>
标签:网络编程 eve use symbol 数据 serve ... [1] ack
原文地址:https://www.cnblogs.com/xiao-apple36/p/9286610.html