1 # server.py 2 3 import socket 4 import subprocess 5 6 sk = socket.socket() 7 8 sk.bind(('127.0.0.1', 8081)) 9 sk.listen(5) 10 11 while True: 12 conn, addr = sk.accept() 13 while True: 14 try: 15 16 recv_data = conn.recv(1024) 17 if len(recv_data) == 0:break 18 p = subprocess.Popen(str(recv_data, encoding='utf8'), shell=True, stdout=subprocess.PIPE) 19 res = p.stdout.read() 20 if len(res) == 0: 21 send_data = 'cmd_err' 22 23 else: 24 send_data = str(res, encoding='gbk') 25 26 send_data = bytes(send_data, encoding='utf8') 27 28 ready_tag = 'Ready|%s' % len(send_data) 29 30 # 这一步是关键,向客户端发送 消息和数据大小 31 conn.send(bytes(ready_tag, encoding='utf8')) 32 33 feedback = conn.recv(1024) 34 # 收到客户端的消息 35 feedback = str(feedback, encoding='utf8') 36 # 开始发送数据 37 if feedback.startswith('Start'): 38 conn.send(send_data) 39 except Exception: 40 break 41 42 conn.close() 43 44 45 # client.py 46 47 import socket 48 49 cli = socket.socket() 50 51 cli.connect(('127.0.0.1', 8081)) 52 53 while True: 54 55 send_data = input('>>:').strip() 56 if send_data == 'exit':break 57 if len(send_data) == 0:continue 58 cli.send(bytes(send_data, encoding='utf-8')) 59 # 收到消息 60 ready_tag = cli.recv(1024) 61 ready_tag = str(ready_tag, encoding='utf-8') 62 if ready_tag.startswith('Ready'): 63 msg_size = int(ready_tag.split('|')[-1]) 64 65 # 告知服务端,我收到了消息 66 start_tag = 'Start' 67 cli.send(bytes(start_tag, encoding='utf8')) 68 69 recv_size = 0 70 recv_msg = b'' 71 72 while recv_size<msg_size: 73 recv_data = cli.recv(1024) 74 recv_msg += recv_data 75 recv_size += len(recv_data) 76 77 print('MSG SIZE %s RECE SIZE %s' % (msg_size, recv_size)) 78 print(str(recv_msg, encoding='utf8')) 79 80 81 cli.close()
与原始的socke交互相比,个人理解就是在客户端向服务端发起请求,服务端在响应之前主动向客户端发送信号(| 数据的大小),多了一个交互的过程