我试图在我的php函数下面设置一个超时,以避免页面加载需要一段时间,但我需要通过php在页面加载时将tcp消息发送到ip和端口,如何设置超时如果ip和端口无法访问?
我尝试过使用下面的socket_set_option方法,但不幸的是它需要30秒,有时甚至更长。
我在laravel 5.2项目中使用它
public static function send($command, $data = '')
{
$MUSdata = $command . chr(1) . $data;
$socket = \socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
$connect_timeval = array(
"sec"=>0,
"usec" => 100
);
\socket_set_option(
$socket,
SOL_SOCKET,
SO_SNDTIMEO,
$connect_timeval
);
\socket_connect($socket, Config::get('frontend.client_host_ip'), Config::get('frontend.mus_host_port'));
\socket_send($socket, $MUSdata, strlen($MUSdata), MSG_DONTROUTE);
\socket_close($socket);
}
答案 0 :(得分:1)
我根据Brian comment写了一个connect_with_timeout
函数:
不幸的是,SO_SNDTIMEO不会影响连接超时;连接套接字后才进行写操作。您需要将套接字置于非阻塞模式,为连接编写自己的超时循环(将返回EAGAIN直到套接字连接),然后将套接字重新置于阻塞模式。
如果套接字及时连接,则该函数返回true,否则返回false。
$timeout
是以秒为单位的超时,$con_per_sec
是每秒的连接尝试次数。
function connect_with_timeout($soc, $host, $port, $timeout = 10) {
$con_per_sec = 100;
socket_set_nonblock($soc);
for($i=0; $i<($timeout * $con_per_sec); $i++) {
@socket_connect($soc, $host, $port);
if(socket_last_error($soc) == SOCKET_EISCONN) {
break;
}
usleep(1000000 / $con_per_sec);
}
socket_set_block($soc);
return socket_last_error($soc) == SOCKET_EISCONN;
}
在Windows和Linux上测试,PHP 5.x