这是我写的程序一部分,接收到数据通过bin2hex转换之后打印数据,为了验证是分段我加了sssss标识 [attach]2471[/attach] 下面是结果图
[attach]2472[/attach] .... [attach]2473[/attach]
tcp本来就是分段传输,没毛病
我要是想将这个整个数据存到数据库,应该怎么处理哪
弄个通讯协议,发数据的时候按照协议格式发。 比如 workerman的text协议,格式就是数据末尾加一个换行符"\n",注意PHP里是双引号。 workerman的话就是 $tcp_worker = new Worker('text://0.0.0.0:1234'); 客户端发数据的话在末尾加一个换行符来表示数据包结束。PHP代码类似: $client = stream_socket_client('tcp://127.0.0.1:1234'); // 注意,text协议格式是数据末尾加换行符 "\n",注意是双引号,之前吃过这个亏 fwirte($client, '36K数据'."\n"); 按照服务端的协议格式发就能完整接收了。当然你可以定义其它协议,workerman文档里有定义方法,自定义协议我还没用过。 http://doc.workerman.net/protocols/why-protocols.html http://doc.workerman.net/protocols/why-protocols.html http://doc.workerman.net/protocols/example.html
好的谢谢!
问题已经解决 问题原因:tcp协议本身是分段传输的,这个传输的大小可能就是几十k左右。 解决方法:需要自定义通讯协议(其原理还是基于tcp传输,只是在接收数据的时候进行了判断) 自定义协议方法:http://doc.workerman.net/protocols/how-protocols.html 自定义协议代码:
<?php namespace Workerman\Protocols; /** * Lxy Protocol. */ class Lxy { // workerman接收数据的过程(workerman手册上有描述,在定制通讯协议那里) //1、假设客户端发送一个数据包给服务端,服务端收到数据(可能是部分数据)后会立刻调用协议的 input 方法,用来检测这个包的长度,input方法会返回数据包长度$length(也就是通讯协议告诉workerman框架我要这么长的数据) // 2、workerman框架会判断当前缓冲区里面有没有这么长的数据,如果没有就继续等待,直到数据长度达到要求。 // 3、然后框架会从缓冲区中取出这么长的数据,调用decode方法,decode方法就是将数据进行处理,处理完成之后将数据return到onMessage,这样我们就可以在onMessage编写业务代码了。 //定义自己要接收到的数据有多长 const PACKAGE_LEN = 36018; public static function input($recv_buffer) { // $recv_buffer 接收到的数据 // $data_len 获取当前的数据长度 $data_len = strlen($recv_buffer); // 如果不够数据长度,则继续等待 if($data_len < self::PACKAGE_LEN) { return 0; } // 数据达到长度,返回包长,这里返回的包长,相当于告诉decode方法,要从缓冲区中取出这么长的数据 return $data_len; //================================================ // //这里是我的项目中需要传输二进制数的逻辑,如果你只是传输较长的字符串,这里可以不用看 // // 我的项目中,是硬件设备通过tcp协议传输数据,硬件方面传输的时候是16进制,但是不知道为什么经过tcp之后变成了二进制(这里没有管他,接收到之后直接由二进制转成十六进制) // $recv_buffer = bin2hex($recv_buffer);//二进制转十六进制 // $data_len = strlen($recv_buffer);//获取转化之后的长度 // // 如果不够数据长度,则继续等待 // if($data_len < self::PACKAGE_HEAD_LEN) // { // return 0; // } // // 返回包长,注意:这里返回的时候又将数据从二进制转成了十六进制了,因为二进制和十六进制的长度不同,decode方法里面要处理的数据是刚传来时的二进制数,所以这里要转回二进制 // $data_len = strlen(hex2bin($recv_buffer)); // return $data_len; // ================================================= } /** * Decode. * * @param string $buffer * @return string */ public static function decode($recv_buffer) { // $recv_buffer : 根据返回的包长,从缓冲区中获取数据 // 测试过程中如果不知道哪里出问题了可以将数据放到文件中查看 : file_put_contents('data_len.txt','data:'.$recv_buffer.PHP_EOL, FILE_APPEND); // 将数据return到onMessage,就完成了简单的自定义协议了 return $recv_buffer; } /** * Encode. * * @param string $buffer * @return string * 这个是给客户端发送数据的,我没用到 */ public static function encode($data) { return $data; } } workerman程序代码: <?php use Workerman\Worker; use Workerman\Lib\Timer; define('BASE_DIR','。。。'); require_once BASE_DIR . 'Workerman/Autoloader.php'; require_once BASE_DIR . 'worker/mysql-master/src/Connection.php'; $tcp_worker = new Worker("Lxy://0.0.0.0:8282"); $tcp_worker->onWorkerStart = function ($worker) { global $db; //地址,端口,账户,密码,数据库名 $db = new \Workerman\MySQL\Connection('127.0.0.1', '3306', '', '', ''); }; // 启动进程对外提供服务 $tcp_worker->count = 1; //获取客户端ip $tcp_worker->onConnect = function ($connection) { global $db; echo "client connect ip:" . $connection->getRemoteIp() . " port:" . $connection->getRemotePort() . PHP_EOL; $connection->send('connection success'); }; $tcp_worker->onMessage = function($connection, $data){ global $db; var_dump($data); echo 'sssssssssssssssssssssssssss'.PHP_EOL; }; // 运行worker Worker::runAll();
tcp本来就是分段传输,没毛病
我要是想将这个整个数据存到数据库,应该怎么处理哪
弄个通讯协议,发数据的时候按照协议格式发。
比如 workerman的text协议,格式就是数据末尾加一个换行符"\n",注意PHP里是双引号。
workerman的话就是 $tcp_worker = new Worker('text://0.0.0.0:1234');
客户端发数据的话在末尾加一个换行符来表示数据包结束。PHP代码类似:
$client = stream_socket_client('tcp://127.0.0.1:1234');
// 注意,text协议格式是数据末尾加换行符 "\n",注意是双引号,之前吃过这个亏
fwirte($client, '36K数据'."\n");
按照服务端的协议格式发就能完整接收了。当然你可以定义其它协议,workerman文档里有定义方法,自定义协议我还没用过。
http://doc.workerman.net/protocols/why-protocols.html
http://doc.workerman.net/protocols/why-protocols.html
http://doc.workerman.net/protocols/example.html
好的谢谢!
问题已经解决
问题原因:tcp协议本身是分段传输的,这个传输的大小可能就是几十k左右。
解决方法:需要自定义通讯协议(其原理还是基于tcp传输,只是在接收数据的时候进行了判断)
自定义协议方法:http://doc.workerman.net/protocols/how-protocols.html
自定义协议代码: