一,解决粘包问题案例
A 服务端
from socket import *
import subprocess
import struct
phone=socket(AF_INET,SOCK_STREAM)
phone.bind(('127.0.0.1',8081))
phone.listen(5)
print('服务的启动......')
# 连接循环
while True:
conn,client_addr=phone.accept()
print(client_addr)
# 通信循环
while True:
try:
cmd=conn.recv(1024)
if not cmd:break #针对nux系统
obj=subprocess.Popen(cmd.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout=obj.stdout.read()
stderr=obj.stderr.read()
# 1、先发送固定长度的报头
#目前报头里只包含数据的大小
total_size=len(stdout) + len(stderr)
conn.send(struct.pack('i',total_size))
# 2、发送真实的数据
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError:
break
conn.close()
phone.close()
B 客户端
from socket import *
import struct
phone=socket(AF_INET,SOCK_STREAM)
phone.connect(('127.0.0.1',8081))
while True:
cmd=input('>>>: ').strip()
if not cmd:continue
phone.send(cmd.encode('utf-8'))
#1、先收报头,从报头里取出对真实数据的描述信息
header=phone.recv(4)
total_size=struct.unpack('i',header)[0]
#2、循环接收真实的数据,直到收干净为止
recv_size=0
res=b''
while recv_size < total_size:
recv_data=phone.recv(1024)
res+=recv_data
recv_size+=len(recv_data)
print(res.decode('gbk'))
phone.close()
二,终极解决粘包问题案例
A 服务端
from socket import *
import subprocess
import struct
import json
phone=socket(AF_INET,SOCK_STREAM)
phone.bind(('127.0.0.1',8081))
phone.listen(5)
print('服务的启动......')
# 连接循环
while True:
conn,client_addr=phone.accept()
print(client_addr)
# 通信循环
while True:
try:
cmd=conn.recv(1024)
if not cmd:break
obj=subprocess.Popen(cmd.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
stdout=obj.stdout.read()
stderr=obj.stderr.read()
#制作报头
header_dic={
'filename':'a.txt',
'total_size':len(stdout) + len(stderr),
'md5':'xxxxxsadfasdf123234e123'
}
header_json = json.dumps(header_dic)
header_bytes=header_json.encode('utf-8')
#1、先发送报头的长度
conn.send(struct.pack('i',len(header_bytes)))
#2、再发送报头
conn.send(header_bytes)
#3、最后发送真实的数据
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError:
break
conn.close()
phone.close()
B 客户端
from socket import *
import struct
import json
phone=socket(AF_INET,SOCK_STREAM)
phone.connect(('127.0.0.1',8081))
while True:
cmd=input('>>>: ').strip()
if not cmd:continue
phone.send(cmd.encode('utf-8'))
#1、先收报头的长度
obj=phone.recv(4)
header_size=struct.unpack('i',obj)[0]
#2、再接收报头
header_bytes=phone.recv(header_size)
header_json=header_bytes.decode('utf-8')
header_dic=json.loads(header_json)
print(header_dic)
total_size=header_dic['total_size']
#3、循环接收真实的数据,直到收干净为止
recv_size=0
res=b''
while recv_size < total_size:
recv_data=phone.recv(1024)
res+=recv_data
recv_size+=len(recv_data)
print(res.decode('gbk'))
phone.close()