Swoole 网络通信协议,固定包头。
程序员文章站
2022-04-24 15:59:25
网络通信过程中,可能会出现分包和合包的情况。具体情况如https://wiki.swoole.com/wiki/page/484.html文档所讲的。这里测试了下固定包头的协议。示例代码如下 1.解包封装的方法 2.服务端 tcpServer.php 启动服务端 3 客户端 tcpClient.ph ......
网络通信过程中,可能会出现分包和合包的情况。具体情况如https://wiki.swoole.com/wiki/page/484.html文档所讲的。这里测试了下固定包头的协议。示例代码如下
1.解包封装的方法
communicationpack.php
<?php //对数据信息封装 function packdata($senddata,$packmodel){ return pack($packmodel, strlen($senddata)).$senddata; } //解包 function unpackdata($rcvdata,$packmodel){ $length = $packmodel=='n'?4:2; return substr($rcvdata,$length); }
2.服务端 tcpserver.php
<?php require_once 'communicationpack.php'; $packmodel = 'n'; //创建server对象,监听 127.0.0.1:9501端口 $serv = new swoole_server("127.0.0.1", 9501); $serv->set(array( 'open_length_check' => true, 'package_max_length' => 2000000, 'package_length_type' => $packmodel, //see php pack() 'package_length_offset' => 0, 'package_body_offset' => $packmodel=='n'?4:2, )); //监听连接进入事件 $serv->on('connect', function ($serv, $fd) { echo "client: connect.\n"; }); //监听数据接收事件 $serv->on('receive', function ($serv, $fd, $from_id, $data) use($packmodel){ echo "#{$serv->worker_id}>> received length=" . strlen($data) ."data=".$data. "}\n"; $data = unpackdata($data,$packmodel); $returnstr = "server: ".$data; $serv->send($fd, packdata($returnstr,$packmodel)); }); //监听连接关闭事件 $serv->on('close', function ($serv, $fd) { echo "client: close.\n"; }); //启动服务器 $serv->start();
启动服务端
3 客户端 tcpclient.php
<?php require_once 'communicationpack.php'; $packmodel = 'n'; $client = new swoole_client(swoole_sock_tcp); $client->set(array( 'open_length_check' => true, 'package_length_type' => $packmodel, 'package_length_offset' => 0, //第n个字节是包长度的值 'package_body_offset' => $packmodel=='n'?4:2, //第几个字节开始计算长度 'package_max_length' => 2000000, //协议最大长度 )); //连接到服务器 if (!$client->connect('127.0.0.1', 9501, 0.5)) { die("connect failed."); } //向服务器发送数据 //数据协议 $senddata = "test123"; $senddata = packdata($senddata,$packmodel); if (!$client->send($senddata)) { die("send failed."); } //从服务器接收数据 $data = $client->recv(); if (!$data) { die("recv failed."); } echo unpackdata($data,$packmodel); //关闭连接 $client->close();
然后启动客户端
服务端会打印
pack n是将数据转成了无符号32位的数字,这个刚好长度是4个字节,所以设定
package_body_offset=4