php调用stream_get_contents从tcp套接字中获取数据,有时能够调用一次就能获取全部,有时获取为空需要循环查询

发布于 2022-09-07 15:45:54 字数 829 浏览 16 评论 0

<?php

$socket = stream_socket_server('tcp://127.0.0.1:8888',$errno,$errstr,STREAM_SERVER_BIND|STREAM_SERVER_LISTEN);
if(!$socket){

die('failed to create a socket');

}
stream_set_blocking($socket,false);
//监听新连接
$ev = new EvIo($socket,Ev::READ,function ($watcher) use($socket,$clients){

$client = stream_socket_accept($socket);
stream_set_blocking($client,false);
//监听客户端信息
$e = new EvIo($client,Ev::READ|Ev::WRITE,function ($watcher) use($client){
    $data = stream_get_contents($client);
    echo $data;//有时输出为空,有时完整输出
    /* do{
        $data = stream_get_contents($client);
    }while($data==false);
    发现有时一次就能获取,有时需要重复调用知道获取到
    */
    fclose($client);
    $watcher->stop();
});
Ev::run();

});
Ev::run();

请问是什么原因造成的

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伪心 2022-09-14 15:45:54

你要知道TCP是流式协议,没有消息边界的,UDP是有消息边界的,所以你发送端的数据,到接收端这边,可能需要一次,或者两次,或者一次把两次发送的数据都接收了
610439-20160528150523303-1600111497.png
你可以想象你是在接收水流,所以你是不知道它那里结束的
可以搜索TCP粘包问题,一般解决方案有:

  • 发送定长包。如果每个消息的大小都是一样的,那么在接收对等方只要累计接收数据,直到数据等于一个定长的数值就将它作为一个消息。
  • 包尾加上rn标记。FTP协议正是这么做的。但问题在于如果数据正文中也含有rn,则会误判为消息的边界。
  • 包头加上包体长度。包头是定长的4个字节,说明了包体的长度。接收对等方先接收包体长度,依据包体长度来接收包体。
  • 使用更加复杂的应用层协议。
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文