解决粘包问题-强化版
server------------------
#!/usr/bin/env python
# encoding: utf-8
# Date: 2018/6/5
import socket
import subprocess
import struct
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(('127.0.0.1', 8081))
phone.listen(5)
print('starting.......')
while True: # 链接循环,保证客户端停止,服务端不停止,但是不支持并发
conn, client_addr = phone.accept()
print(client_addr)
while True:
try: # window异常捕获
# 1 接收命令
cmd = conn.recv(1024)
if not cmd: # 适用于linux
break # 客户端断掉,发送空过来
print('客户端的数据', cmd)
# 2 执行命令,拿到结果
obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
# 3把命令的结果返回客户端
# 第一步:制作固定长度的报头
total_size = len(stdout) + len(stderr)
header = struct.pack('i', total_size)
# 第二步,把数据报头发送给客户端
conn.send(header)
# # print(len(stdout) + len(stderr))
# total_size = len(stdout) + len(stderr)
# conn.send(str(total_size).encode('utf-8'))
# 第三步,再发送真实的数据
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError:
break
conn.close()
phone.close()
client--------------------
#!/usr/bin/env python
# encoding: utf-8
# Date: 2018/6/5
import socket
import struct
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(('127.0.0.1', 8081))
while True:
# 1发命令
cmd = input('>>>:').strip()
if not cmd:continue
phone.send(cmd.encode('utf-8')) # 应用程序发给操作系统,操作系统调用网卡
# 那命令结果
# 第一步:先收报头
header = phone.recv(4)
# 第二部:从包头中解析出对真实数据的描述信息(数据的长度)
total_size = struct.unpack('i', header)[0]
# 第三步:接收真实的数据
recv_size = 0
recv_data = b''
while recv_size < total_size:
res = phone.recv(1024)
recv_data += res
recv_size += len(res)
print(res.decode('utf-8'))
phone.close()