💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
>[info] TCP粘包问题的处理 1. 特殊字符 * 根据客户端与服务端相互约定的特殊的符号,对接收的数据进行分割处理 2. 固定包头+包体协议(主流) * 通过与在数据传输之后会在tcp的数据包中携带上数据的长度,然后呢服务端就可以根据这个长度,对于数据进行截取 >[info] 特殊字符 ![](https://img.kancloud.cn/a9/de/a9de40b778631a8fcc3e90f8e05d455c_751x231.png) 1. **使用原生PHP处理** * **服务端代码** ~~~ <?php echo swoole_get_local_ip()['ens33'] . ':9503' . PHP_EOL; // 实例化swoole 服务端 $server = new Swoole\Server("0.0.0.0", 9503); // 连接 $server->on('connect', function ($server, $fd){ echo "connection open: {$fd}\n"; }); // 消息 $server->on('receive', function ($server, $fd, $reactor_id, $data) { // 把字符串打散为数组 var_dump(explode("\r\n" , $data)); echo '接收到数据:' . $fd . "\n"; $server->send($fd, "Swoole:ok"); // $server->close($fd); }); // 关闭 $server->on('close', function ($server, $fd) { echo "connection close: {$fd}\n"; }); // 打开 $server->start(); ~~~ * **客户端代码** ~~~ <?php // 实例化客户端 $client = new Swoole\Client(SWOOLE_SOCK_TCP); // 建立连接 if (!$client->connect('127.0.0.1', 9503, -1)) { exit("connect failed. Error: {$client->errCode}\n"); } // 结尾 $end = "\r\n"; // 循环发送信息 for ($i = 0;$i < 20;$i++) { // 发送 $client->send("hello_world_" . $end); } // 获取服务端数据 echo $client->recv(); // 不断开连接 // while (true){} // 关闭 //$client->close(); ~~~ * **执行效果** 1. 开启服务端监听 * 得到的数据是已经处理好了的 ![](https://img.kancloud.cn/69/e7/69e7e7ed770d333e6b661a978a7d9f88_434x203.png) 2. 客户端运行 ![](https://img.kancloud.cn/0b/4e/0b4e9fc259a370b4c826aa553533e97f_645x83.png) 2. **使用swoole 内置函数处理粘包问题** 函数:**open_eof_check** 手册地址:https://wiki.swoole.com/#/server/setting?id=open_eof_check ![](https://img.kancloud.cn/bb/35/bb351fbcdf23a5db86b3b82d835d7188_1050x522.png) * **服务端代码** ~~~ <?php echo swoole_get_local_ip()['ens33'] . ':9503' . PHP_EOL; // 实例化swoole 服务端 $server = new Swoole\Server("0.0.0.0", 9503); $server->set([ 'open_eof_check' => true, //打开EOF检测 'package_eof' => "\r\n", //设置EOF ]); // 连接 $server->on('connect', function ($server, $fd){ echo "connection open: {$fd}\n"; }); // 消息 $server->on('receive', function ($server, $fd, $reactor_id, $data) { echo '接收到数据:' . $data . "\n"; $server->send($fd, "Swoole:ok"); // $server->close($fd); }); // 关闭 $server->on('close', function ($server, $fd) { echo "connection close: {$fd}\n"; }); // 打开 $server->start(); ~~~ * **客户端代码** ~~~ <?php // 实例化客户端 $client = new Swoole\Client(SWOOLE_SOCK_TCP); // 建立连接 if (!$client->connect('127.0.0.1', 9503, -1)) { exit("connect failed. Error: {$client->errCode}\n"); } // 结尾 $end = "\r\n"; // 循环发送信息 for ($i = 0;$i < 20;$i++) { // 发送 $client->send("hello_world_" . $end); } // 获取服务端数据 echo $client->recv(); // 不断开连接 // while (true){} // 关闭 //$client->close(); ~~~ * **执行效果** 1. 开启服务端监听 ![](https://img.kancloud.cn/1b/16/1b16a441a978812a99774d94a36742f0_426x161.png) 2. 客户端执行 ![](https://img.kancloud.cn/f4/5b/f45b8f1421efa257865f7e3a3bdd5c69_595x163.png) ***** >[info] 固定包头+包体协议 客户端和服务端都需要设置,并且type类型和offset偏移都需要保持一致。 ![](https://img.kancloud.cn/28/4a/284a2b665c46242dc31b7c9866d1b9b8_807x413.png) * 函数:**open_length_check** 手册地址:https://wiki.swoole.com/#/server/setting?id=open_length_check ![](https://img.kancloud.cn/37/1b/371b4746a7d022e491748d1f2d3f6e89_1212x272.png) * **客户端代码** ~~~ <?php // 实例化客户端 $client = new Swoole\Client(SWOOLE_SOCK_TCP); // 建立连接 if (!$client->connect('127.0.0.1', 9503, -1)) { exit("connect failed. Error: {$client->errCode}\n"); } // pack() # 将数据打包成一个二进制字符串 // unpack() # 解析二进制字符 // 循环发送信息 for ($i = 0;$i < 10;$i++) { $conText = '123'; // 利用pack 打包长度 $len = pack('n' , strlen($conText)); var_dump($len); // 组包 $sendData = $len . $conText; var_dump($sendData); // 发送 $client->send($sendData); } // 获取服务端数据 echo $client->recv(); // 不断开连接 // while (true){} // 关闭 //$client->close(); ~~~ * **服务端代码** ~~~ <?php echo swoole_get_local_ip()['ens33'] . ':9503' . PHP_EOL; // 实例化swoole 服务端 $server = new Swoole\Server("0.0.0.0", 9503); // 配置 $server->set([ 'open_length_check' => true, 'package_max_length' => 1 * 1024 * 1024, 'package_length_type' => 'n', 'package_length_offset' => 0, 'package_body_offset' => 2, ]); // 连接 $server->on('connect', function ($server, $fd){ echo "connection open: {$fd}\n"; }); // 消息 $server->on('receive', function ($server, $fd, $reactor_id, $data) { /* var_dump($data); // 解包 $fooLen = unpack('n' , substr($data , 0 , 2))[1]; var_dump($fooLen); // 得到真正的数据 $conText = substr($data , 2 , $fooLen); var_dump($conText);*/ echo "接收到数据:" . $data . PHP_EOL; $server->send($fd, "Swoole:ok"); // $server->close($fd); }); // 关闭 $server->on('close', function ($server, $fd) { echo "connection close: {$fd}\n"; }); // 打开 $server->start(); ~~~ * **运行效果** 1. 开启服务端监听 ![](https://img.kancloud.cn/9c/20/9c20fcdf37c32a0cf1018f87d2db27a2_553x200.png) 2. 客户端运行 ![](https://img.kancloud.cn/3d/5f/3d5fa291ae7885f41847cc44191e0a8b_586x149.png)