你自己想一想
  • 1
  • 新人请关照

swoole 处理粘包和分包问题,如何处理二进制数据包。

swoole 粘包处理问题,swoole 粘包处理是设置 open_eof_split 和 package_eof 的 当客户端发送的数据是文本是可以处理粘包的 但是 实际项目中 客户端上传的是二进制字节流 设置处理粘包就没有用了

阅读 826
评论 2019-06-09 提问
    3 个回答
    宇润
    • 687
    评论 赞赏 2019-06-10

      可以自己设置一个函数 package_length_func

      评论 赞赏 2019-06-11
        王航
        • 4
        • 新人请关照

        swoole支持固定包头+包体和以EOF为结尾的两种分包。
        具体代码实现可以参考ti-rpc,这个代码片段。

            public static function encode(array $data, $type = "tcp")
            {
                if ('tcp' == $type) {
                    if ('eof' == self::$tcpPack) {
                        $data = json_encode($data) . '\r\n';
                    } else if ('length' == self::$tcpPack) {
                        $data = json_encode($data);
                        $data = pack('N', strlen($data)) . $data;
                    }
                    return $data;
                } else {
                    return json_encode($data);
                }
            }
        
            /*
             * @desc : 配置packet的拆包方式
             */
            public static function decode($jsonString, $type = "tcp")
            {
                if ('tcp' == $type) {
                    if ('eof' == self::$tcpPack) {
                        $jsonString = str_replace('\r\n', '', $jsonString);
                    } else if ('length' == self::$tcpPack) {
                        $header = substr($jsonString, 0, 4);
                        $len = unpack('Nlen', $header);
                        $len = $len['len'];
                        $jsonString = substr($jsonString, 4, $len);
                    }
                    return json_decode($jsonString, true);
                } else {
                    return json_decode($jsonString, true);
                }
            }
        

        https://wiki.swoole.com/wiki/...
        以EOF分包,有两种情况,一种是以末尾的EOF进行分包,一种是以数据中出现的EOF进行分包,后者效率比较低。
        然后就是包头定长+包体这种了。
        首先要知道网络字节序,以及本地字节序,说白了就是多字节在传输中的先后顺序
        https://www.v2ex.com/t/330173
        大端 :数据的高字节放在内存的低地址上,小端反之。
        php中常用的函数就是pack()和unpack()两个函数。
        上边代码就是先获取数据长度,然后用4字节的整型格式写入二进制字符串中。
        最后解包,然后根据长度截取数据。
        在swoole中也有相关的配置,如一楼给你的链接

        评论 赞赏 2019-07-01
          撰写回答

          登录后参与交流、获取后续更新提醒