【问题标题】:socket_connect does not timeoutsocket_connect 没有超时
【发布时间】:2013-05-17 09:31:01
【问题描述】:

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

Make PHP socket_connect timeout

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秒。

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

【问题讨论】:

  • usec 是微秒,你为什么设置为 0?
  • @RobertPodwika 因为我希望它精确到 1 秒和 0 微秒

标签: php sockets timeout


【解决方案1】:

您可以通过切换到非阻塞套接字来执行此操作,循环直到获得连接或达到超时,然后再次返回阻塞。

// 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 答案以获得更简洁的解决方案

【讨论】:

  • +1 谢谢。我使用了不同的机制。这很容易改变。看我的回答
【解决方案2】:

我将我的套接字通信机制改为使用stream_socket_client ($remote_socket, &$errno, &$errstr, $timeout) 函数。这个函数允许定义连接超时,而socket_connect ($socket, $address, $port) 没有。

要使用socket_connect 强制超时,请参阅@bigtallbill 答案。

【讨论】:

  • 这绝对是更整洁 :P 虽然它确实返回文件资源而不是套接字资源,所以用例绝对是需要考虑的事情。我对套接字内部结构不够流利,说使用任何一种方法是否更好。
【解决方案3】:

我尝试了很多带有套接字的变体..

fsockopen 最适合简单操作,例如。测试连接

【讨论】:

    【解决方案4】:

    SO_RCVTIMEO/SO_SNDTIMEO 选项在某些平台上不适用于 socket_connect,而仅适用于 socket_recv/socket_send。我可以看到它适用于 Ubuntu,但不适用于 Mac OSX。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 2012-06-30
      • 1970-01-01
      • 2013-08-07
      相关资源
      最近更新 更多