
python入门开发学习笔记之粘包现象与解决方案
发布日期:2025-05-13 01:17:47
浏览次数:2
分类:精选文章
本文共 3637 字,大约阅读时间需要 12 分钟。
粘包问题及其解决方案
粘包问题(Glue Problem)在网络通信中是一个常见的现象,尤其是在使用TCP协议进行通信时。粘包问题的核心在于接收端接收到的数据并非完整的消息片段,而是部分或全部消息的数据片段与前后消息的数据混合在一起。这一问题的出现主要源于TCP协议的面向流特性,使得消息的边界信息不明确。
粘包问题的原因
TCP的面向流特性:TCP协议将数据视为无结构的字节流,不关心数据的边界。发送方可能将多个小数据块合并成一个大数据块发送给接收方,而接收方也可能不以固定大小的数据块来读取数据,这导致消息片段被混合。
缓冲区处理:发送方和接收方都有自己的缓冲区,数据在传输过程中会被临时存储,可能导致部分数据被拆分或混合。
Nagle算法:TCP协议为了提高传输效率,使用Nagle算法将多个小数据块合并成一个大数据块发送。如果连续发送的数据块间隔较小,Nagle算法会将它们合并成一个TCP段。
粘包问题的解决方法
明确消息边界:
- 消息头:在消息前发送一个包含消息长度的消息头,通知接收方下一次将要发送的数据量。
- 消息体:接收方在已知消息长度后,继续读取数据,直到读取完所有数据为止。
自定义报头:
- 使用结构化数据序列化技术(如JSON或XML),并加上自定义报头,包含消息类型、长度和其他元数据信息。
- 例如,发送方先发送一个报头,包含消息长度和元数据,接收方根据报头信息读取完整的消息数据。
优化数据传输策略:
- 合理设置接收缓冲区大小,避免数据片段被拆分。
- 使用高效的数据传输协议或机制,减少数据拆分和粘包的可能性。
应用层协议设计:
- 在应用层定义明确的消息协议,规定消息的格式和边界,确保发送方和接收方能够正确解析数据。
优化方法示例
普通青年版:
- 服务器端:
import socket, subprocessip_port = ('127.0.0.1', 8080)s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)s.bind(ip_port)s.listen(5)while True: conn, addr = s.accept() print('客户端', addr) while True: cmd = conn.recv(1024) if not cmd: break res = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stderr = res.stderr.read() stdout = res.stdout.read() data_length = len(stdout) conn.send(str(data_length).encode('utf-8')) data = conn.recv(1024).decode('utf-8') if data == 'recv_ready': conn.sendall(stdout) conn.close()
- 客户端:
import socketip_port = ('127.0.0.1', 8080)s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)res = s.connect_ex(ip_port)while True: msg = input('> : ').strip() if len(msg) == 0: continue if msg == 'quit': break s.send(msg.encode('utf-8')) length = int(s.recv(1024).decode('utf-8')) s.send('recv_ready'.encode('utf-8')) send_size = 0 recv_size = 0 data = b'' while recv_size < length: data += s.recv(1024) recv_size = len(data) print(data.decode('utf-8'), end='')
文艺青年版二:
- 服务器端:
import socket, struct, jsonip_port = ('127.0.0.1', 8080)phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)phone.bind(ip_port)phone.listen(5)while True: conn, addr = phone.accept() while True: cmd = conn.recv(1024) if not cmd: break res = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) err = res.stderr.read() stdout = res.stdout.read() back_msg = err if err else stdout headers = {'data_size': len(back_msg)} head_json = json.dumps(headers) head_json_bytes = bytes(head_json, encoding='utf-8') phone.send(struct.pack('i', len(head_json_bytes))) phone.send(head_json_bytes) phone.sendall(back_msg) conn.close()
- 客户端:
from socket import *import struct, jsonip_port = ('127.0.0.1', 8080)client = socket(AF_INET, SOCK_STREAM)client.connect(ip_port)while True: cmd = input('> : ').strip() if not cmd: continue if cmd == 'quit': break client.send(bytes(cmd, encoding='utf-8')) head = client.recv(4) head_json_len = struct.unpack('i', head)[0] head_json = json.loads(client.recv(head_json_len).decode('utf-8')) data_len = head_json['data_size'] recv_size = 0 recv_data = b'' while recv_size < data_len: recv_data += client.recv(1024) recv_size = len(recv_data) print(recv_data.decode('utf-8'), end='')
总结
粘包问题源于TCP协议的面向流特性,解决方法包括明确消息边界、使用自定义报头、优化数据传输策略等。选择具体方法需根据应用场景和性能需求综合考量。
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2025年05月12日 21时04分37秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
2025版万字长文入门大语言模型(LLM)零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新0基础怎么转行网络安全?零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新Bash Shell入门指南,零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新C++快速入门(适合小白)零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新关于HW护网行动的一些知识,零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新大模型学习路线,零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新大模型开发流程(非常详细)零基础入门到精通,收藏这一篇就够了
2023-01-25
2025版最新大模型微调方法(非常详细)零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新大语言模型的指令微调,零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新小白学习大模型:什么是大模型?零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新常用黑客工具之【Nmap 教程基础】零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新渗透测试和黑客工具列表,零基础入门到精通,收藏这一篇就够了
2023-01-25
2025版最新网络安全等级保护测评指南,零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新运维怎么转行网络安全?零基础入门到精通,收藏这篇就够了
2023-01-25
2025版最新黑客学习网站(非常详细),零基础入门到精通,看这一篇就够了
2023-01-25
2025版网络工程11个高含金量证书(非常详细)零基础入门到精通,收藏这篇就够了
2023-01-25
2025自学成为黑客必读的5本书籍,带你从小白进阶成大佬
2023-01-25
23张图告诉你组建一个网络需要用到哪些硬件设备?路由器、交换机、防火墙是不是就够了?
2023-01-25
#12 btrfs文件系统
2023-01-25