协议:
####{‘type’:’测试’}
前四位为小端序,表示数据包(不含前4位)长度
后面为json数据包
workerman协议实现:
<?php
namespace Protocols;
class JsonRX
{
public static function input($recv_buffer)
{
// 接收到的数据还不够4字节,无法得知包的长度,返回0继续等待数据
if(strlen($recv_buffer)<4)
{
return 0;
}
// 利用unpack函数将首部4字节转换成数字,首部4字节即为整个数据包长度
$unpack_data = unpack(‘Vtotal_length’, $recv_buffer);
// 接收到的数据长度不够,返回0继续等待数据
if(strlen($recv_buffer)<$unpack_data[‘total_length’]+4){
return 0;
}
return $unpack_data[‘total_length’]+4;
}
public static function decode($recv_buffer)
{
// 去掉首部4字节,得到包体Json数据
$body_json_str = substr($recv_buffer, 4);
// json解码
return json_decode($body_json_str, true);
}
public static function encode($data)
{
// Json编码得到包体
$body_json_str = json_encode($data);
// 计算整个包的长度,包体字节数
$total_length = strlen($body_json_str);var_dump($total_length);
// 返回打包的数据
return pack(‘V’,$total_length) . $body_json_str;
}
}
原生测试代码数据实现(已知数据包长度)
<?php
$data = json_encode([
‘cmd’ => 101,
‘response’ => [
‘page’ => 1,
‘page_size’ => 50,
‘board_id’ => 34,
]
]);
//发送的数据包
$send = pack(‘V’,strlen($data)).$data;
$ip = “127.0.0.1”;
$port = 8189;
//
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)or die(“Could not create socket\n”);
$connection = socket_connect($socket, $host, $port) or die(“Could not connet server\n”);
socket_write($socket, $send) or die(“Write failed\n”);
//读取前四位,获取数据包长度
$buff = @socket_read($socket, 4);
$unpack_data = unpack(‘Vtotal_length’, $buff);
$content_len = $unpack_data[‘total_length’];
$per_len = 20000; //每次读多少字节
$no_read_len = $content_len; //未读的字节(总字节大小)
$str = ‘’;
$len = 0;
while($len<$content_len)
{
$read = socket_read($socket, $per_len,PHP_BINARY_READ);
$str .= $read;//读取的数据
$len += strlen($read); //总共读了多少字节
}
var_dump($len);
$data = json_decode($str,true);
var_dump($data);
socket_close($socket);