Python--网络编程-----通过socket收发文件软件开发--面向对象开发
服务端实现
1 import socket 2 import struct 3 import json 4 import os 5 6 7 class MYTCPServer: 8 address_family = socket.AF_INET 9 socket_type = socket.SOCK_STREAM 10 allow_reuse_address = False 11 max_packet_size = 8192 12 coding = 'utf-8' 13 request_queue_size = 5 14 server_dir = r'C:\Users\xudachen\PycharmProjects\Python全栈开发\第三模块\网络编程\通过socket发送文件\服务端\file_upload' 15 16 def __init__(self, server_address, bind_and_active=True): 17 """Constructor. May be extended, do not override""" 18 self.server_address = server_address 19 self.socket = socket.socket(self.address_family, self.socket_type) 20 21 if bind_and_active: 22 try: 23 self.server_bind() 24 self.server_activate() 25 except: 26 self.server_close() 27 raise 28 29 def server_bind(self): 30 """Called by constructor to bind the socket""" 31 if self.allow_reuse_address: 32 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 33 self.socket.bind(self.server_address) 34 self.server_address = self.socket.getsockname() 35 36 def server_activate(self): 37 """Called by constructor to activate the server""" 38 self.socket.listen(self.request_queue_size) 39 40 def server_close(self): 41 """Called to clean-up the server""" 42 self.socket.close() 43 44 def get_request(self): 45 """Get the request and client address from the socket""" 46 return self.socket.accept() 47 48 def close_request(self, request): 49 """Called to clean-up an individual request""" 50 request.close() 51 52 def run(self): 53 while True: 54 self.conn, self.client_addr = self.get_request() 55 print('from client', self.client_addr) 56 while True: 57 try: 58 head_struct = self.conn.recv(4) 59 if not head_struct: 60 break 61 62 head_len = struct.unpack('i', head_struct)[0] 63 head_json = self.conn.recv(head_len).decode(self.coding) 64 head_dic = json.loads(head_json) 65 66 print(head_dic) 67 cmd = head_dic['cmd'] 68 if hasattr(self, cmd): 69 func = getattr(self, cmd) 70 func(head_dic) 71 except Exception: 72 break 73 74 def put(self, args): 75 file_path = os.path.normpath(os.path.join(self.server_dir, args['filename'])) 76 77 filesize = args['filesize'] 78 recv_size = 0 79 print('---->', file_path) 80 with open(file_path, 'wb') as f: 81 while recv_size < filesize: 82 recv_data = self.conn.recv(self.max_packet_size) 83 f.write(recv_data) 84 recv_size += len(recv_data) 85 print('recvsize:%s filesize:%s' % (recv_size, filesize)) 86 87 88 tcpserver1 = MYTCPServer(('127.0.0.1', 8080)) 89 tcpserver1.run()
客户端实现
1 import socket 2 import struct 3 import json 4 import os 5 6 7 class MYTCPClient: 8 address_family = socket.AF_INET 9 socket_type = socket.SOCK_STREAM 10 allow_reuse_address = False 11 max_packet_size = 8192 12 coding = 'utf-8' 13 request_queue_size = 5 14 15 def __init__(self, server_address, connect=True): 16 self.server_address = server_address 17 self.socket = socket.socket(self.address_family, self.socket_type) 18 19 if connect: 20 try: 21 self.client_connect() 22 except: 23 self.client_close() 24 raise 25 26 def client_connect(self): 27 self.socket.connect(self.server_address) 28 29 def client_close(self): 30 self.socket.close() 31 32 def run(self): 33 while True: 34 inp = input(">>:").strip() # put test.py 35 if not inp: 36 continue 37 l = inp.split() # ['put','test.py'] 38 cmd = l[0] # put 39 if hasattr(self, cmd): 40 func = getattr(self, cmd) 41 func(l) 42 43 def put(self, args): # ['put','test.py'] 44 cmd = args[0] # put 45 filename = args[1] # test.py 46 if not os.path.isfile(filename): 47 print('file:%s is not exists' % filename) 48 return 49 else: 50 filesize = os.path.getsize(filename) 51 52 head_dic = {'cmd': cmd, 53 'filename': os.path.basename(filename), 54 'filesize': filesize} 55 print(head_dic) 56 head_json = json.dumps(head_dic) 57 head_json_bytes = bytes(head_json, encoding=self.coding) 58 59 head_struct = struct.pack('i', len(head_json_bytes)) 60 self.socket.send(head_struct) 61 self.socket.send(head_json_bytes) 62 send_size = 0 63 with open(filename, 'rb') as f: 64 for line in f: 65 self.socket.send(line) 66 send_size += len(line) 67 print(send_size) 68 else: 69 print('upload successful') 70 71 72 client = MYTCPClient(('127.0.0.1', 8080)) 73 client.run()
先启动服务端,再启动客户端,在客户端输入put test.py
客户端运行结果为;
1 >>:put test.py 2 {'cmd': 'put', 'filename': 'test.py', 'filesize': 1014} 3 17 4 20 5 61 6 83 7 86 8 128 9 140 10 142 11 187 12 201 13 241 14 253 15 255 16 268 17 294 18 313 19 328 20 354 21 386 22 398 23 400 24 413 25 416 26 440 27 443 28 477 29 489 30 504 31 507 32 536 33 593 34 632 35 651 36 687 37 723 38 779 39 805 40 807 41 822 42 856 43 877 44 879 45 894 46 896 47 955 48 988 49 1014 50 upload successful 51 >>:
服务端运行结果:
1 from client ('127.0.0.1', 55771) 2 {'cmd': 'put', 'filename': 'test.py', 'filesize': 1014} 3 ----> C:\Users\xudachen\PycharmProjects\Python全栈开发\第三模块\网络编程\通过socket发送文件\服务端\file_upload\test.py 4 recvsize:1014 filesize:1014
实际效果:
注意,在windows系统中使用pycharm,上传成功后,并不会立即在上传文件夹中显示,需要找到文件夹路径,点进去,然后才会在pycharm中看到,