包裹是按件发送的.我有两个选择;我可以设置缓冲区并将整个包装整合在一起,或者在完成所有传输后组合碎片.我认为第一个选项(缓冲物)是正确的方法.
我正在定义缓冲区大小,但它在第一部分不起作用.在其他部分,它的工作原理,但使用这种方法我不能将整个包装整体,因为第一部分限制为5,24 Kb.
你可以在下面找到我的代码:
$loop = React\EventLoop\Factory::create(); $dnsResolverFactory = new React\Dns\Resolver\Factory(); $dns = $dnsResolverFactory->createCached('8.8.8.8',$loop); $connector = new React\SocketClient\Connector($loop,$dns); $connector->create( ENDPOINT_IP,ENDPOINT_PORT )->then(function (React\Stream\Stream $stream) use ($loop) { $command = '{C:"EL",bmId:43,inst:"my_instance",tok:"my_token"}'; $command_length = strlen($command); $command_length = pack("N",$command_length); $stream->write($command_length); $stream->write($command); $stream->bufferSize = 999999; $stream->on('data',function ($data) { $package = substr($data,4); $unpack = unpack('N',$package); // I'm getting whole package size echo $data; }); }); $loop->run();
我尝试在$stream-> on(‘data’,function($data){line下定义一个缓冲区大小,但是你猜它失败了.我不知道如何正确处理它.
提前致谢.
第一种选择不是正确的方式,因为它不是套接字通信的工作方式.
例如,如果您正在接收5 kB数据,并且您将缓冲区设置得足够大,那么假设10 kB,您不能指望在一次调用$stream-> on(‘data’,function($data) ){…你将获得全部5 kB.
你必须做三件事:
>您需要知道在一个消息块中接收的数据的确切大小.您要么知道消息将始终具有固定且已知的大小,要么数据块具有可以从中读取消息长度的标头.在您的情况下,您正在从接收数据的前4个字节中读取消息大小.
>在循环中,您需要读取来自服务器的数据块并将它们连接起来,直到您有足够的字节来读取整个消息的大小.在你的情况下,这是4个字节.无论听起来多么奇怪,你有可能在两个块中收到1个然后3个字节,在两个调用$stream-> on(‘data’,function($data){….当大小时连接数据> = 4然后您读取消息的大小.
>在同一个循环中,您需要继续读取来自套接字的数据块并将它们连接起来,直到您收到所有消息字节为止.当然,这意味着您需要在循环外部定义一个存储接收数据的变量.收到整条消息后,您需要退出循环.
好主意是你为循环设置了一个定时器,这样你就可以等待有限的时间内收到整个消息.可能会发生客户端和服务器之间的连接在传输过程中被破坏,如果您没有超时逻辑,您的循环将永远等待接收整个消息.