socket connect 反复使用,为何到一定的时候connect不上服务器?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socket connect 反复使用,为何到一定的时候connect不上服务器?相关的知识,希望对你有一定的参考价值。

参考技术A 多半是服务器忙,另外socket传完了数据,是要关闭的。追问

连完是关闭了的。这个问题只在windows下出现。

socket_connect没有超时

我正在使用套接字将数据发送到可能没有响应的服务器。所以我试图通过在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秒后强制连接创建超时?

答案

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

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

另一答案

我改变了我的套接字通信机制,改为使用stream_socket_client ($remote_socket, &$errno, &$errstr, $timeout)函数。与socket_connect ($socket, $address, $port)不同,此函数允许定义连接超时。

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

另一答案

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

另一答案

我尝试了很多带插座的变种..

fsockopen是最简单的操作,例如。测试连接

以上是关于socket connect 反复使用,为何到一定的时候connect不上服务器?的主要内容,如果未能解决你的问题,请参考以下文章

高性能网络通信库中为何要将侦听 socket 设置成非阻塞的?

你想知道的Socket,统统打包给你~

Linux 怎样实现非阻塞connect

将 socket.io 与 Mean 集成时反复出现 404 错误

c ++ linux socket服务器反复调用客户端

socket_connect没有超时