一、什么是粘包
TCP是字节流协议,数据传输像流水一样。数据发送者会存在一个发送缓冲区,每次可能会将多个数据包一次性发送出去,也可能是一个数据包拆分多次发出去;如果协议没有约定好分隔符或者不明确数据包大小边界,接收者就无法获取并正确解析数据包了,这就是常说的 粘包,下面结合swoole_server和自定义协议来详细说明。二、 常见的自定义协议
1. 固定包大小
发送者和接收者约定数据包长度,适合需求较简单,消息类型固定的情况,灵活性很差。2. EOF结束符
发送者和接收者约定数据包已一个特殊的结束符(EOF)做结尾。适合协议相对简单的需求,常见的比如 redis、memcache、ftp、stmp等都是用\r\n换行符作为结束符。3. 固定包头+包体协议
发送者和接收者约定数据开始于一个固定长度的消息头(header),消息头里包含包体(body)的长度数据和一些其他的自定义校验数据,这样接收者就能从数据流中,根据包体的长度来截取剩下的数据包。这样的自定义协议更加灵活,且便于接收者分割数据。现在我们来定义一个业务自己的协议,使用固定包头+包体的格式。
固定包头长度8
前6个字节表示协议头,固定为字符 SWOOLE
后2个字节为int16,无符号短整型(16位,大端字节序) ,表示后面的包体长度。这里涉及到大小端字节序的问题,推荐看看知乎专栏 “字节序”是个什么鬼?
三、Swoole\Server
使用swoole_server 我们能很轻易的实现一个TCP服务,使用者无需关注底层实现细节,就能达到使用 TCP/UDP/UnixSocket 搭建异步服务器的要求;在php中,一般使用 pack/unpack 方法封包解包二进制数据,再通过swoole发送出去。swoole_server()->set() 方法中提供了一些处理自定义协议的 属性设置,通过这些设置,swoole基本不用考虑粘包问题了,真好
网友回复
有没有免费让ai自动帮你接管操作电脑的mcp服务?
mcp为啥用Streamable HTTP 替代 HTTP + SSE?
scratchjr有没有开源的前端html网页版本源代码?
多模态大模型能否根据ui交互视频来来模仿写出前端交互动画效果ui代码?
如何用阿里云oss+函数计算fc+事件总线EventBridge+消息队列+数据库+redis缓存打造一个高并发弹性系统?
阿里云函数计算 FC如何在海外节点搭建一个代理网络?
ai studio中gemini build的代码如何发布到github pages等免费网页托管上 ?
如何在cursor、qoder、trae中使用Claude Skills功能?
有没有不用u盘就能重装系统的开源工具?
python如何固定摄像头实时计算停车场停车位剩余数量?


