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

时间:2022-09-22 13:36:16
   项目中经常用到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++服务已经回报,抓包数据如下: UDP socket_read接收数据导致错误Resource temporarily unavailable

ICMP回报表示C++服务 230 发送的UDP包没有程序socket_read没有接收    
这就是问题tcpdump显示数据已经发送  但是socket_read显示Resource temporarily unavailable

后来测试正常的请求才发现 ,服务器发送数据的端口从11188 变成成了11177 ,下面是可以收到的抓包
UDP socket_read接收数据导致错误Resource temporarily unavailable

后来发现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回报未接收到数据 UDP socket_read接收数据导致错误Resource temporarily unavailable