先上图
server 端
client 客户端
原文参考 https://blog.csdn.net/ldy3243942/article/details/40920743
3.固定包头类型协议
固定包头协议是在实际应用中最常用的协议。该协议的内容是规定一个固定长度的包头,在包头的固定位置有一个指定好的字段存放了后续数据的实际长度。这样,服务器端可以先读取固定长度的数据,从中提取出长度,然后再读取指定长度的数据,即可获取一段完整的数据。
在Swoole中,同样提供了固定包头的协议格式。需要注意的是,Swoole只允许二进制形式的包头,因此,需要使用pack、unpack来打包、解包。
通过设置open_length_check选项,即可打开固定包头协议解析功能。此外还有package_length_offset,package_body_offset和package_length_type三个配置项用于控制解析功能。package_length_offset规定了包头中第几个字节开始是长度字段,package_body_offset规定了包头的长度,package_length_type规定了长度字段的类型。
具体设置如下:
$this->serv->set(array(
'package_max_length' => 8192,
'open_length_check'=> true,
'package_length_offset' => 0,
'package_body_offset' => 4,
'package_length_type' => 'N'
));
具体如何设置这些参数请参考文档
OK,废话不多讲,直接上实例:
服务器端:
public function onReceive( swoole_server $serv, $fd, $from_id, $data ) {
$length = unpack("N" , $data)[1];
echo "Length = {$length}\n";
$msg = substr($data,-$length);
echo "Get Message From Client {$fd}:{$msg}\n";
}
客户端:
$msg_length = pack("N" , strlen($msg_normal) ). $msg_normal;
$i = 0;
while( $i < 100 ) {
$this->client->send( $msg_length );
$i ++;
}
直接运行,Perfect!
点此查看完整实例
下面是server代码 稍作修改
<?php class Server { private $serv; public function __construct() { $this->serv = new swoole_server("0.0.0.0", 9501); $this->serv->set(array( 'worker_num' => 8, 'daemonize' => false, 'max_request' => 10000, 'dispatch_mode' => 2, 'package_max_length' => 8192, 'open_length_check'=> true, 'package_length_offset' => 0, 'package_body_offset' => 4, 'package_length_type' => 'N' )); $this->serv->on('Start', array($this, 'onStart')); $this->serv->on('Connect', array($this, 'onConnect')); $this->serv->on('Receive', array($this, 'onReceive')); $this->serv->on('Close', array($this, 'onClose')); $this->serv->start(); } public function onStart( $serv ) { echo "Start\n"; } public function onConnect( $serv, $fd, $from_id ) { echo "Client {$fd} connect\n"; } public function onReceive( swoole_server $serv, $fd, $from_id, $data ) { print($data); file_put_contents("2.txt",$data); //This is a Msg echo "\n"; print_r(unpack("N",$data)); /* Array ( [1] => 13 ) */ $length = unpack("N" , $data)[1]; echo "Length = {$length}\n"; $msg = substr($data,-$length); echo "Get Message From Client {$fd}:{$msg}\n"; } public function onClose( $serv, $fd, $from_id ) { echo "Client {$fd} close connection\n"; } } new Server();
客户端代码 client
<?php class Client { private $client; public function __construct() { $this->client = new swoole_client(SWOOLE_SOCK_TCP); } public function connect() { if( !$this->client->connect("127.0.0.1", 9501 , 1) ) { echo "Error: {$fp->errMsg}[{$fp->errCode}]\n"; } $msg_normal = "This is a Msg"; // $msg_eof = "This is a Msg\r\n"; // echo pack("N" , strlen($msg_normal) ); $msg_length = pack("N" , strlen($msg_normal) ). $msg_normal; file_put_contents("1.txt",$msg_length); $i = 0; while( $i < 5 ) { $this->client->send( $msg_length ); $i ++; } } } $client = new Client(); $client->connect(); ~
看下1.txt 发现前面变成看不懂的 也就是二进制流
到此为止 就结束了 server端应该也是收到流才对
再看下server 的2.txt
server 端生成的 同样也是二进制再开头的
大概就这样了