Swoole TCP 流数据边界问题解决方案

本文详细探讨了Swoole在TCP通信中遇到的数据边界问题,介绍了EOF解决方案,包括open_eof_check和open_eof_split的差异,并推荐使用固定包头+包体的高效分包方式。此外,还提及了字节序的基础知识。
摘要由CSDN通过智能技术生成

1. 数据发送过程

我的官方群点击此处

首先由客户端将数据发往缓冲区 (服务端并不是直接收到的), 对于客户端来说,这次的数据即是发送成功了, 对于服务端是否真正的收到他是不知道的, 然后再由服务端从缓冲区中读取数据。图解:

 

 

 

2. 什么是数据边界

 

因为 TCP 是流式传输,对于服务端来说并不知道此时在缓冲区内的数据是一次请求还是两次请求的,所以在服务端接收数据时需要根据指定字符或约定长度来对数据进行分包,这个分包的标志即是数据边界。否则可能会出现一次读取两条或多条数据,造成读取、解析数据出错。

 

 

 

2.1 代码演示

可以用代码实现一下,假设客户端死循环往缓冲区不停输入 “1”,即相当于每次的报文内容都是 1, 那么在服务端读取时收到的数据就是随机长度的。

客户端代码

$client = new Swoole\Client(SWOOLE_SOCK_TCP);
if ($client->connect('127.0.0.1', 9501, -1)) {
    while(true) {
        $client->send(1);        
    }
}
$client->close();

服务端代码

$server = new Swoole\Server('127.0.0.1', 9501);
$server->on('connect', function($server, $fd){
    echo "client : ".$fd." connect";
});

$server->on('receive', function($server, $fd, $from_id, $data){
    echo "receive:". $data.PHP_EOL;
});

$server->on('close', function($server){

});

运行结果

 

 

 

可以看到运行结果,服务端获取到的数据完全是随机的,有长有短,那么接下来我们说下如何解决这个问题。

 

3.EOF 解决方案

第一种解决方案类似于我们 http 请求头的分隔符,在每次发送的数据包结尾处使用 \r\n (可以配置) 来结尾, 当服务端从缓冲区中读取数据, 根据指定字符来分割数据包,EOF 有两种配置方案:

3.1 open_eof_check

首先放出配置方式:

$server->set([
    'open_eof_check' => true,
    'package_eof' => "\r\n"
]);

这种配置方式会对客户端发来的数据包进行检测, 当发现结尾是 \r\n 时,才会投递给 worker 进程, 也就是我们的 onReceive 回调,否则会一直拼

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值