socket_connect 不会超时 [英] socket_connect does not timeout

查看:38
本文介绍了socket_connect 不会超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用套接字将数据发送到可能没有响应的服务器.所以我试图通过在 SO 中使用这个解决方案来定义超时.

I am using sockets to send data to a server that may not be responding. So I am trying to define a timeout by using this solution in SO.

使 PHP socket_connect 超时

socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 1, 'usec' => 0));
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => 1, 'usec' => 0));

这在建立连接并且服务器响应时间过长时起作用.但是当它不能创建连接时 socket_connect($socket, $addr, $port); 超时大约是 20 秒.

This works when the connection is made and the server takes too long to respond. But when it can't create a connection socket_connect($socket, $addr, $port); the timeout is about 20 seconds.

为什么会发生 20 秒的超时,我如何强制连接创建也在 1 秒后超时?

Why is this 20 second timeout happening and how can I force the connection creation to timeout after 1 second too?

推荐答案

您可以通过切换到非阻塞套接字来实现此目的,循环直到获得连接或达到超时,然后再次返回阻塞状态.

You can do this by switching to a non-blocking socket, looping until either a connection is gained or a timeout was reached, then back to blocking again.

// an unreachable address
$host = '10.0.0.1';
$port = 50000;
$timeout = 2;

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// switch to non-blocking
socket_set_nonblock($sock);

// store the current time
$time = time();

// loop until a connection is gained or timeout reached
while (!@socket_connect($sock, $host, $port)) {
    $err = socket_last_error($sock);

    // success!
    if($err === 56) {
        print('connected ok');
        break;
    }

    // if timeout reaches then call exit();
    if ((time() - $time) >= $timeout) {

        socket_close($sock);
        print('timeout reached!');
        exit();
    }

    // sleep for a bit
    usleep(250000);
}

// re-block the socket if needed
socket_set_block($sock);

如果您使用的是通过 fsockopen() 或 stream_socket_client() 创建的套接字,请参阅 @letiagoalves 答案以获得更简洁的解决方案

edit: see @letiagoalves answer for an neater solution if you are using sockets created with fsockopen() or stream_socket_client()

这篇关于socket_connect 不会超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆