socket_connect does not timeout

后端 未结 4 1889
说谎
说谎 2021-01-03 09:48

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.

Make PHP socket_connect time

相关标签:
4条回答
  • 2021-01-03 10:20

    I tried a lot of variants with sockets..

    fsockopen the best for simple operations, ex. testing connections

    0 讨论(0)
  • 2021-01-03 10:23

    The SO_RCVTIMEO/SO_SNDTIMEO options don't work for socket_connect on some platforms, but only for socket_recv/socket_send. I can see it works on Ubuntu, but not Mac OSX.

    0 讨论(0)
  • 2021-01-03 10:33

    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);
    

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

    0 讨论(0)
  • 2021-01-03 10:40

    I changed my socket communication mechanism to use stream_socket_client ($remote_socket, &$errno, &$errstr, $timeout) function instead. This function allows to define the connect timeout unlike socket_connect ($socket, $address, $port) which doesn't.

    To force a timeout using socket_connect see @bigtallbill answer.

    0 讨论(0)
提交回复
热议问题