粘包问题的本质是,在TCP协议下,客户端/服务端将两次发送的内容认为是一次传输所引起的问题,以下是粘包问题的相应代码:
1. 服务端
import socket import subprocess import struct import json service = socket.socket(socket.AF_INET, socket.SOCK_STREAM) service.bind(('127.0.0.1', 8080)) service.listen(5) # print('start....') while True: conn, addr = service.accept() print(addr) while True: try: cmd = conn.recv(1024) obj = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = obj.stdout.read() stderr = obj.stderr.read() header_dict = {'header_size': len(stderr) + len(stdout), 'name': 'file_name', 'md5':'hhdjfjjkioiuiuywe'} header_json = json.dumps(header_dict) header_bytes = header_json.encode( 'utf-8') num = len(header_bytes) conn.send(struct.pack('i', num)) # total_size = len(stderr) + len(stdout) # header = struct.pack('i', total_size) conn.send(header_bytes) conn.send(stdout) conn.send(stderr) except Exception: break conn.close() service.close()
2.客户端
from socket import * import struct import json client=socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8080)) # print(client) while True: cmd=input('>>>: ').strip() if not cmd:continue client.send(cmd.encode('utf-8')) #1、先收报头的长度 header_size=struct.unpack('i',client.recv(4))[0] #2、接收报头 header_bytes=client.recv(header_size) #3、解析报头 header_json=header_bytes.decode('utf-8') header_dic=json.loads(header_json) print(header_dic) total_size=header_dic[ 'total_size'] # print(total_size) #1025 #4、根据报头内的信息,收取真实的数据 recv_size=0 res=b'' while recv_size < total_size: recv_data=client.recv(1024) res+=recv_data recv_size+=len(recv_data) print(res.decode('gbk')) client.close()