解决网络编程的粘包问题
# 服务端
import socket
import subprocess
import struct
import json
import subprocess
import struct
import json
servers = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
servers.bind(('127.0.0.1', 7777))
servers.listen(10)
print('start settings')
servers.bind(('127.0.0.1', 7777))
servers.listen(10)
print('start settings')
while True:
"""连接循环"""
conn, adder = servers.accept()
print('客服端的信息:', adder)
"""连接循环"""
conn, adder = servers.accept()
print('客服端的信息:', adder)
while True:
"通信循环"
try:
cmd = conn.recv(1024) # 1收命令
"通信循环"
try:
cmd = conn.recv(1024) # 1收命令
# 2执行命令的结果丢到管道里面存起来
obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# 3从管道里面拿出数据
stdout = obj.stdout.read()
stderr = obj.stderr.read()
stdout = obj.stdout.read()
stderr = obj.stderr.read()
# 4制作报头
header_dict = {'filename': 'a.txt',
'md5': 'xxxx',
'total_size': len(stdout)+len(stderr)}
header_dict = {'filename': 'a.txt',
'md5': 'xxxx',
'total_size': len(stdout)+len(stderr)}
# 4.1制作固定长度的报头
header_json = json.dumps(header_dict)
header_bytes = header_json.encode('utf-8')
header_size = struct.pack('i', len(header_bytes))
header_json = json.dumps(header_dict)
header_bytes = header_json.encode('utf-8')
header_size = struct.pack('i', len(header_bytes))
# 4.2发送固定长度的报头
conn.send(header_size)
conn.send(header_size)
# 4.3再发送报头的信息
conn.send(header_bytes)
conn.send(header_bytes)
# 5再发送真实的数据
conn.send(stdout)
conn.send(stderr)
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError:
break
conn.close()
break
conn.close()
servers.close()
# 客服端
import struct
import json
import socket
import struct
import json
import socket
client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
client.connect(('127.0.0.1', 7777))
client.connect(('127.0.0.1', 7777))
while True:
"""通信循环"""
cmd = input('输入要执行的命令:').strip() # 收命令
if not cmd:continue
client.send(cmd.encode('utf-8')) # 发送命令
"""通信循环"""
cmd = input('输入要执行的命令:').strip() # 收命令
if not cmd:continue
client.send(cmd.encode('utf-8')) # 发送命令
"""先收报头的长度"""
obj = client.recv(4) # 收固定长度的报头
header_size = struct.unpack('i', obj)[0]
obj = client.recv(4) # 收固定长度的报头
header_size = struct.unpack('i', obj)[0]
"""在收报头"""
header_bytes = client.recv(header_size)
header_bytes = client.recv(header_size)
"""再从报头中解析出对真实数据的描叙信息"""
header_json = header_bytes.decode('utf-8')
header_dict = json.loads(header_json)
total_size = header_dict['total_size']
header_json = header_bytes.decode('utf-8')
header_dict = json.loads(header_json)
total_size = header_dict['total_size']
"""再接受真实的数据"""
recv_size = 0
recv_data = b''
while recv_size < total_size:
result = client.recv(1024)
recv_size += len(result)
recv_data += result
recv_size = 0
recv_data = b''
while recv_size < total_size:
result = client.recv(1024)
recv_size += len(result)
recv_data += result
print(recv_data.decode('gbk'))
client.close()