swoole提供了内置包长检测的方法,该方法提供了固定包头 + 包体这种格式协议的解析。
启用后,可以保证 Worker 进程 onReceive 每次都会收到一个完整的数据包。
长度检测协议,只需要计算一次长度,数据处理仅进行指针偏移,性能非常高,推荐使用。
可见官方是推荐使用这种方式的,就是配置比其他方案要复杂一些, 首先贴一下配置:
$server->set([
// 打开包长检测特性
'package_length_check' => true,
// 包头中某个字段作为包长度的值,底层支持了 10 种长度类型。可参考 pack() 方法
'package_length_type' => 'N',
// length 长度值在包头的第几个字节。
'package_length_offset' => 8,
// 从第几个字节开始计算长度,一般有 2 种情况:
//length 的值包含了整个包(包头 + 包体),package_body_offset 为 0
//包头长度为 N 字节,length 的值不包含包头,仅包含包体,package_body_offset 设置为 N
'package_body_offset' => 16,
// 设置最大数据包尺寸,单位为字节
'package_max_length' => 81920
]);
下面是一个数据包结构例子,可以很好的体现了字段含义。
下面看具体的示例代码:
tcp服务端代码
<?phptcp客户端代码
$serv = new Swoole\Server('127.0.0.1', 9502);
$serv->set([
'open_length_check' => true,
'package_max_length' => 81920,
'package_length_type' => 'N',
'package_length_offset' => 8,
'package_body_offset' => 16,
]);
$serv->on('connect', function($server, $fd){
echo $fd. " Connect !".PHP_EOL;
});
$serv->on('receive', function($server, $fd, $from_id, $data){
$length = unpack('N', $data)[1];
echo "Length:".$length.PHP_EOL;
$msg = substr($data, -$length);
echo "Msg:".$msg.PHP_EOL;
var_dump($data); // 源数据
$tmp = unpack("Ntype/Nuid/Nlength", $data);
$unpacking = unpack("Ntype/Nuid/Nlength/Nserid/a{$tmp['length']}body", $data);
var_dump($unpacking); // 解包后数据
$server->send($fd, " Server Receive Data: ". $unpacking['body']);
});
$serv->on('close', function($server){
});
$serv->start();
$client = new Swoole\Client(SWOOLE_SOCK_TCP);
$data = "123456789012345678901234567890";
$type = 0x30;
$uid = 0x123;
$length = strlen($data);
$serid = 0x15;
$head = pack("N4", $type, $uid, $length, $serid);
$body = pack("a{$length}", $data);
$message = $head.$body;
if ($client->connect('127.0.0.1', 9502, -1)) {
$client->send($message);
echo $client->recv();
}
$client->close();
网友回复
DLNA与UPnP的区别和不同?
苏超自建抢票app,通过先预约再抽签化解高并发抢票?
python如何让给电脑在局域网中伪装成电视接收手机的投屏图片视频播放?
如何结合python+js如何自己的视频编码与加密播放直播?
python如何在电脑上通过局域网将本地视频或m3u8视频投屏电视播放?
腾讯视频爱奇艺优酷vip电影电视剧视频如何通过python绕过vip收费直接观看?
有没有可免费观看全球电视台直播m3u8地址url的合集?
有没有实现观影自由的免vip影视苹果 CMS V10 API的可用url?
python如何实时检测电脑usb插入检测报警?
如何判断真人操作的鼠标移动直线轨迹与机器操作的轨迹?