swoole 4 通过底层协议机制自动处理 tcp 粘包与拆包,核心是让服务端准确识别业务数据包边界:启用 open_eof_split 和 package_eof 实现 eof 结束符自动分包,或配置 open_length_check、package_length_type 等参数支持固定包头+包体协议,使 onreceive 每次收到完整消息。

Swoole 4 中处理 TCP 粘包问题,核心在于让服务端能准确识别每个业务数据包的边界。它不依赖应用层手动缓存+解析,而是通过底层协议支持自动完成分包与合包,真正把“粘包”变成透明过程。
为什么会出现粘包和拆包
TCP 是字节流协议,本身没有消息概念。客户端连续发几段小数据(比如 "a\r\n"、"b\r\n"、"c\r\n"),内核可能合并成一个 TCP 段发出;而服务端一次 recv() 可能拿到全部,也可能只拿到前半截。这不是 bug,是 TCP 的正常行为。Swoole 4 的协议机制,就是为了解决这种不确定性。
EOF 结束符协议(最常用)
适用于每条消息以固定字符串结尾的场景,比如换行符 \r\n 或自定义标记 "|END|"。关键配置如下:
- open_eof_split => true:启用自动按 EOF 拆包(推荐,比 open_eof_check 更可靠)
- package_eof => "\r\n":指定结束符,最长 8 字节,必须确保业务数据中不出现
- package_max_length => 8192:单个包最大长度,防止恶意超长数据阻塞
启用后,onReceive 回调每次收到的 $data 都是一个完整消息(不含 EOF),无需再手动截断或循环查找。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
固定包头 + 包体协议(更健壮)
当消息内容不可控(可能含任意字符),EOF 方案就不安全。这时用长度前缀法:在每条消息开头写入 2–4 字节的长度值,Swoole 自动读取并截取对应字节数。
- open_length_check => true:开启长度检查
- package_length_type => "N":指定长度字段类型("n"=ushort, "N"=uint, "V"=uint little-endian)
- package_length_offset => 0:长度字段从包头第几个字节开始
- package_body_offset => 4:实际数据从第几个字节开始(如长度占 4 字节,则 body 从 offset=4 开始)
例如发送 pack("N", 5) . "hello",Swoole 会先读 4 字节得长度 5,再读后续 5 字节作为完整消息。
多协议共存与协议识别
Swoole 4 支持单端口多协议混合接入。常见做法是:在 onReceive 中先判断数据特征,再交由不同解析器处理。
- 检测前 2 字节是否为
0x1603→ 判定为 TLS/HTTPS 流量,转给 HTTP Server 处理 - 检测开头是否为
"GET "或"POST "→ 交给内置 HTTP 协议栈 - 检测是否以
0x02开头且第 3 字节为命令码 → 路由到自定义二进制协议处理器
也可用 listen() 绑定多个端口,分别为 HTTP、TCP、WebSocket 设置不同协议和回调,物理隔离更清晰。










