18

I was wondering how can I set a timeout on a socket_read call? The first time it calls socket_read, it waits till data is sent, and if no data is sent within 5 secs I want to shutdown the connection. Any Help? I already tried SO_RCVTIMEO with no luck.

I'm creating a socket with socket_create() and listening on it for connections, then when connected I listen for the data and then do something with it. When the timeout hits, I want to run socket_shutdown() and then socket_close().

James Hartig
  • 1,009
  • 1
  • 9
  • 20
  • Please take to the note that Windows Sockets API doesn't work with timeouts less then 500 ms. You can set timeout to much smaller amount of time, but while you will be on Windows platform you should know that this probably will not work as you wanted to. Reference: http://www.microsoft.com/mspress/books/WW/sampchap/4287d.aspx . – excanoe Jul 13 '12 at 18:12

4 Answers4

27

this set 5 sec timeout of the socket.

socket_set_option($socket,SOL_SOCKET, SO_RCVTIMEO, array("sec"=>5, "usec"=>0));
Nick
  • 9,962
  • 4
  • 42
  • 80
  • after some testing - this appears to be the lifetime of the entire socket - no just the socket_read – roocell Dec 15 '11 at 23:18
  • 11
    Interesting observation: if you use PHP_NORMAL_READ instead of PHP_BINARY_READ (default) as the third argument to socket_read(), it will ignore the timeout set using socket_set_option() and will block indefinitely until something is sent... (observed with PHP 5.5.9) – 2072 Mar 04 '14 at 23:00
  • Another interesting observation: It does not work if you remove ` usec` from the array – Dushyant Bangal Jul 13 '18 at 05:15
  • does not work reliable, you can't trust it. I have plenty of cases where it hangs for minutes even though timeout of few milliseconds is configured. Might depend on TCP flags – John Feb 09 '19 at 08:31
  • 1
    Setting this on the main `$socket` created with `socket_create()` will affect both `socket_accept()` timeout and `socket_read()` timeout. To affect just socket_read() timeout, set this on the second socket name created with `$socket_name = socket_accept()`. – adrianTNT Aug 01 '20 at 12:41
12

Have you tried socket_set_option with SO_RCVTIMEO

Timeout value for input operations.

OIS
  • 9,833
  • 3
  • 32
  • 41
5

I did a socket_listen and then I made a manual timeout with time()+2 and a while loop with nonblock set and socket_read() inside. Seems to be working ok. Any alternatives?

UPDATE: I found that setting the socket as nonblocking and then using socket_listen provided the timeout I needed.

James Hartig
  • 1,009
  • 1
  • 9
  • 20
  • 1
    Oooh, you're accepting socket connections with PHP. That's a bit different. http://us3.php.net/manual/en/function.socket-select.php Select will return sockets if there is anything available to be read, otherwise time out with your specified timeout. – Steven Behnke Dec 23 '08 at 19:49
1
$read_socket = socket_select($read, $write  = NULL, $except = NULL, 10); // 10 - Timeout
if($read_socket === FALSE)
    $this->End();
elseif($read_socket === 0)
    return FALSE;

$pdu_ = socket_read($this->session, 102400);
if($read_socket && !strlen($pdu_))
    $this->End();
kfb
  • 6,252
  • 6
  • 40
  • 51