php中使用swoole实现头协议
当需要有数据交互的时候,为了安全起见,双方会协商一个固定的头协议,这样必须实现其头协议才能拿到数据。
PHP的swoole完美的提供了固定包头+包体协议自动分包。
首先需要通过open_length_check打开固定包头包体协议,再用package_length_offset规定包头中第几个字节是整个包长度,package_body_offset是从第几个字节开始计算长度,比如包头为长度为120字节,第10个字节为长度值,包体长度为1000。如果长度包含包头,这里填入0,如果不包含包头,这里填入120。最后一个是package_length_type,表示长度字段的类型,涉及到网络字节序和机器字节序,都是以字节为单位的。详细信息可以自己去了解。配置如下:
$this->serv->set(array(
'open_length_check' => true, //打开固定包头协议解析功能
'package_length_offset' => 0, //规定了包头中第几个字节开始是长度字段
'package_body_offset' => 0, //length的值包含了整个包(包头+包体)
'package_length_type' => 'N', //规定了长度字段的类型
));
php中的pack和unpack可以用来处理和解析网络字节序。比如:我们发的包头是
$length=40+strlen($data);
$serv->send($fd, pack("N", $length));
$serv->send($fd, pack("C", $msg_type));
$serv->send($fd, pack("C", $replyCipher));
$serv->send($fd, pack("C", $compress));
$serv->send($fd, $uuid); $serv->send($fd,$data);
也许有人会问,为什么长度是40加上包体长度,因为我们这里的N是无符号、网络字节序、4字节,而是无符号、1字节,然后规定uuid的长度是为33个字节,所以整个包头长度为33+4+1+1+1,那就是40了。至于各个字段的意义,那是看你们自己的定义的。
包头发了,肯定就有解析,这里只说明PHP对以上包头的解析。其实很简单,只是按照上面的顺序逐一用unpack解析出来就可以了。
//获取整个消息的长度
$msg_length = unpack("N", $data)[1];
$data = substr($data, 4);
// echo "整个消息的长度:".$msg_length.PHP_EOL; //消息类型
$msg_type = unpack("C", $data)[1];
$data = substr($data, 1);
// echo "消息类型:".$msg_type.PHP_EOL; //服务端响应包体是否需要加密标识 0-不需要加密 1-需要加密 保留字段
$replyCipher = unpack("C", $data)[1];
$data = substr($data, 1);
// echo "响应包体是否加密标识:".$replyCipher.PHP_EOL; //获取包体是否需要压缩标识 0-未压缩 1-压缩 保留字段
$compress = unpack("C", $data)[1];
$data = substr($data, 1);
// echo "包体是否压缩标识:".$compress.PHP_EOL; //请求者ID
$uuid = substr($data, 0, 33);
// echo "请求者ID:". $uuid.PHP_EOL; //获取包体
$data = substr($data, 33);
// echo $data;
因为开启了open_length_check,所以swoole会在你接收到全部的数据后,才开始对数据进行处理。不过我有一点不明白,为什么接收到整个数据后,用unpack("N", $data)[1]就可以接收到第一个传的数据?望知道的大神不吝赐教!
php中使用swoole实现头协议的更多相关文章
- spring拦截器中修改响应消息头
问题描述 前后端分离的项目,前端使用Vue,后端使用Spring MVC. 显然,需要解决浏览器跨域访问数据限制的问题,在此使用CROS协议解决. 由于该项目我在中期加入的,主要负责集成shiro框架 ...
- 协议分析中的TCP/IP网络协议
- 链路层 第一层包含源mac及目的mac,随着传输路径的变化会发生变化,在mac之后,是下层网络协议的类型,图中,下层为IP协议. 在协议解析中,需要关注的是图中type这个字段的内容. - 网络层 ...
- 原生ajax中readyState中的含义以及HTTP协议状态码的含义
xmlhttp.readyState的值及解释: 0:请求未初始化(还没有调用 open()). 1:请求已经建立,但是还没有发送(还没有调用 send()). 2:请求已发送,正在处理中(通常现在可 ...
- 浅谈VC++中预编译的头文件放那里的问题分析
用C++写程序,肯定要用预编译头文件,就是那个stdafx.h.不过我一直以为只要在.cpp文件中包含stdafx.h 就使用了预编译头文件,其实不对.在VC++中,预编译头文件是指放到stdafx. ...
- 转-Web Service中三种发送接受协议SOAP、http get、http post
原文链接:web服务中三种发送接受协议SOAP/HTTP GET/HTTP POST 一.web服务中三种发送接受协议SOAP/HTTP GET/HTTP POST 在web服务中,有三种可供选择的发 ...
- IE高级配置中,存在SSL支持协议,例如SSL TLS。
IE高级配置中,存在SSL支持协议,例如SSL TLS. 其在注册表的路径为:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\I ...
- 分布式环境中,模块数据交互协议分析 (百度brpc)
1. 背景 之前听到同事说,要为自己的模块考虑写个数据协议.今天有空想了一下.写出来,方便后续使用. 开源代码brpc中可以支持多种协议,nshead.redis.mongo等20多种协议. 2. 什 ...
- Laravel 中使用 swoole 项目实战开发案例二 (后端主动分场景给界面推送消息)
推荐阅读:Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信) 需求分析 我们假设有一个需求,我在后端点击按钮 1,首页弹出 “后端触发了按钮 1”.后端点了 ...
- 【git】git中使用https和ssh协议的区别以及它们的用法
git可以使用四种主要的协议来传输资料: 本地协议(Local),HTTP 协议,SSH(Secure Shell)协议及 git 协议.其中,本地协议由于目前大都是进行远程开发和共享代码所以一般不常 ...
随机推荐
- PHP操作Memcached
一.PHP连接Memcached: 一个简单的使用示例: $memcache = new Memcache; $memcache->connect("127.0.0.1",1 ...
- 26.Linux-网卡驱动(详解)
1.描述 网卡的驱动其实很简单,它还是与硬件相关,主要是负责收发网络的数据包,它将上层协议传递下来的数据包以特定的媒介访问控制方式进行发送, 并将接收到的数据包传递给上层协议. 网卡设备与字符设备和块 ...
- Bower+grunt-wiredep自动注入包到html
以安装jquery为例 1.假设已经通过npm安装好了bower和grunt-wiredep,以及grunt-contrib-watch(用来观察文件变动) 在gruntfile.js文件中增加任务 ...
- MarkDown的快速入门
简介 简单的去解释MarkDown就是html,但是将html中的元素用符号去代替使用.本文用的编译软件是Atom(神器),不多说直接上图看效果. 语法 文本 列表 区块 分割符 表格 链接 mark ...
- 暑假练习赛 003 F Mishka and trip
F - Mishka and trip Sample Output Hint In the first sample test: In Peter's first test, there's on ...
- ssh秘钥分发错误“/usr/bin/ssh-copy-id: ERROR: No identities found”
在做ssh的时候出现下面的错误,这个错误根本没有遇到过啊,仔细一看,后面的端口不对,我要发到的服务器端口是22,我想肯定是这个原因,结果不加端口,还是提示 这个错误,于是咨询下其他人,结果发现要分发的 ...
- linux DHCP安装和测试
1.Yum 安装DHCP服务 2.拷贝模板配置文件,方便后期的配置修改. cp /usr/share/doc/dhcp-4.1.1/dhcpd.conf.sample /etc/dhcp/dhcpd. ...
- 图文详解linux/windows mysql忘记root密码解决方案
经常有用户过来咨询说自己的mysql服务器忘记密码了怎么办,为了更好的解决大家的困扰,本文特归档整理了windows和linux系统下,mysql忘记密码的解决方案.本文内容是我亲测实用,当然过程中踩 ...
- 一起写框架-Ioc内核容器的实现-基础功能-ComponentScan(四)
功能说明 该步骤实现的功能包括: 1. 启动程序时,将@ComponentScan加载的类,创建对象并放在容器里面. 2. 通过ApplicatoinContext的getBean()方法获得容器里面 ...
- 实现验证码图像文字的识别(C#调用DLL)
请先下载http://asprise.com/product/ocr/index.php?lang=csharp 的SDK.里面提供了详细的OCR方法,如下: 将发现图像框picbVeryfyCo ...