`
OrangeHolic
  • 浏览: 259528 次
  • 来自: 北京
社区版块
存档分类
最新评论

UDP socket_read接收数据导致错误Resource temporarily unavailable

    博客分类:
  • PHP
 
阅读更多
项目中经常用到PHP用UDP调用C++服务,我们这边的PHP 请求方法封装如下,一直没有问题出现,今天接入新的服务出现了问题
  
   public static  function request($reqBuffer,$host,$port)
    {

        $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
        //设置发送数据超时时间
        socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array("sec" => 0, "usec" => 500000));
        //设置接收数据超时时间
        socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 0, "usec" => 500000));
        if (socket_connect($socket, $host, $port) === false) {
            socket_close($socket);
            throw new Exception('connect server error'.socket_strerror(socket_last_error()), 100);
        }
        if (socket_write($socket, $reqBuffer, strlen($reqBuffer)) === false) {
            socket_close($socket);
            throw new Exception('send request error'.socket_strerror(socket_last_error()), 100);
        }
        if (($rspBuffer = socket_read($socket, 65536)) === false) {
            socket_close($socket);
            throw new Exception('receive response error'.socket_strerror(socket_last_error()), 100);
        }
        socket_close($socket);
        return $rspBuffer;
    }


问题如下:
socket_read  一直返回false  错误信息:Resource temporarily unavailable,而用tcpdump抓包显示C++服务已经回报,抓包数据如下:



ICMP回报表示C++服务 230 发送的UDP包没有程序socket_read没有接收   

这就是问题tcpdump显示数据已经发送  但是socket_read显示Resource temporarily unavailable


后来测试正常的请求才发现 ,服务器发送数据的端口从11188 变成成了11177 ,下面是可以收到的抓包




后来发现socket_read不能接收端口变化的数据,适合与TCP这种保持连接,整个过程端口不变化的socket,而socket_recvfrom可以处理这种情况

然后函数封装换成了下面的方式:
    public static functionrequest($reqBuffer, $host, $port)
    {

        $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
        //设置发送数据超时时间
        socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array("sec" => 0, "usec" => 500000));
        //设置接收数据超时时间
        socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 0, "usec" => 500000));

        if (socket_sendto($socket,$reqBuffer, strlen($reqBuffer),0,$host,$port) === false) {
            socket_close($socket);
            throw new Exception('send request errorr' . socket_strerror(socket_last_error()), 100);
        }
        $from = "";
        $port = 0;
        if (socket_recvfrom($socket, $rspBuffer, 65536, 0, $from, $port) === false) {
            socket_close($socket);
            throw new Exception('receive response error' . socket_strerror(socket_last_error()), 100);
        }
        socket_close($socket);
        return $rspBuffer;
    }

现在OK了  不在会用ICMP回报未接收到数据



  • 大小: 14.2 KB
  • 大小: 11.1 KB
  • 大小: 9.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics