首页 存档 技术 查看内容

“Swoole”项目开发思维转换之粘包

2018-3-30 13:00 |来自: 互联网 380 0

摘要: swoole是用php快速开发高效的tcp/udp服务, 其中tcp是用的更多的一个场景,http虽然是基于tcp协议的,但和直接开发tcp服务还是有明显的区别的。 TCP是数据流 tcp是数据流,这是一个基本的概念,这里有两个要点: 数 ...

swoole是用php快速开发高效的tcp/udp服务, 其中tcp是用的更多的一个场景,http虽然是基于tcp协议的,但和直接开发tcp服务还是有明显的区别的。

TCP是数据流

tcp是数据流,这是一个基本的概念,这里有两个要点:

  1. 数据没有边界

    你可以理解为水在一个水管里的流动,我们不知道哪段数据是一个我们需要的完整数据

  2. 收发有缓冲区

    比如:当水从一端流到了另一端,我们在收数据的时候,不可能每来一滴水就处理一次,这个缓冲区就相当于有了一个水桶,再接了一定的水之后内核再给数据交到用户空间,这样可以大大提升性能。

那这里就有一个问题:由于这个特性,内核无法知道哪部分数据是你想要的,所以应用层拿到数据可能是完整数据,也可能是不完整或者一部分完整、一部分不完整(粘包,那么怎样能得到想要的数据呢?

数据协议

数据协议可以理解为一种约定,按照这个约定来处理收到的数据进而得到想要的数据,这个过程就称为拆包,那问题又来了?

web开发为什么不用考虑粘包

因为web的http可以理解为一个公共的数据协议,在实现一个web服务器的时候,就必需按照这个协议来进行数据处理,这样保证在应用层获取到数据是完整的数据,http是典型的包头 包体的这个一个约定格式,有那现几个特点:

  1. 通过\r\n\r\n来区分包头和包体

  2. 包头通过\r\n来区分不同的数据组

看个示例:

GET / HTTP/1.1

Host: www.swoole.com

Connection: keep-alive

这是一个典型的请求头,第一行约定了请求的方法(GET/POST/PUT/DELETE等)、请求地址、http协议版本, 从第二行开始,都是健:值的形式,反应到PHP里,就是$_SERVER超全局变里里 HTTP_开头的数据,由于这是GET请求,所有没有包体,如果是POST或者response响应,我们可以看到包体,包体的长度通过包头里的Content-Length参数来控制的

Swoole怎么处理粘包

swoole考虑到在粘包是一个必需处理的过程,内置了两种方案:

  1. 约定结束符

    这个类似于c里面的字符串数组,约定了\0表示字符串结束,在swoole里,可以的setting数组中,开启open_eof_check=true,并用package_eof来设置一个完整数据结尾字符。

    举个例子:

    "open_eof_check"=

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部