粘包
1.什么是粘包:
粘包就是接收方不知道消息的界限,从而使发过来的多个消息/数据粘连在一起的现象
2.为什么会造成粘包:
粘包的情况有两种:
①发送端由于nagle优化算法的原因,会将数据时间间隔很短、数据很小的消息/数据汇合到一起以后再进行发送,产生粘包;
②接受方不及时接收缓冲区的包,造成多个包接收(发送方发送了一段数据,但接收方只收了一小部分,下次发送方再次发送时,接收方会优先拿到上次没有接收完的数据,造成粘包)
3.怎么解决粘包问题
事例:
服务端:
import socket import json import struct import subprocess server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('127.0.0.1', 8083)) server.listen(5) while True: conn, client_addr = server.accept() while True: try: cmd = conn.recv(1024) if len(cmd) == 0: 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 = { 'file_name': '返回文本', 'file_size': len(stderr) + len(stdout), 'md5': 'asgddasgdadag' } header_str = json.dumps(header_dic) header_bytes = header_str.encode('utf-8') conn.send(struct.pack('i', len(header_bytes))) conn.send(header_bytes) conn.send(stdout) conn.send(stderr) except Exception: break conn.close()
客户端:
import socket import json import struct client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1',8083)) while True: cmd = input('>>:').strip() if len(cmd) == 0:continue client.send(cmd.encode('utf-8')) header_size = client.recv(4) header_bytes = client.recv(struct.unpack('i',header_size)[0]) header_str = header_bytes.decode('utf-8') header_dic = json.loads(header_str) file_size = header_dic['file_size'] recv_size = 0 res = b'' while recv_size < file_size: data = client.recv(1024) recv_size += len(data) res += data print(res.decode('gbk'))