5

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

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.

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

2
  • usec are microseconds why did you set it to 0? Commented May 22, 2013 at 11:10
  • @RobertPodwika because I want it to be exacly 1 second and 0 microseconds Commented May 22, 2013 at 12:44

4 Answers 4

4

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

Sign up to request clarification or add additional context in comments.

1 Comment

+1 thanks. I used a different mechanism. it was easy to change. see my answer
2

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.

1 Comment

That is definitely a lot neater :P Though it does return a file resource instead of a socket rescource, so use-case is definitely something to consider. I'm not fluent enough with socket internals say whether using either method is better.
1

I tried a lot of variants with sockets..

fsockopen the best for simple operations, ex. testing connections

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.