Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the proper way to connect a non-blocking socket in linux

Tags:

linux

sockets

I'm new to programming with sockets in Linux and have a question about the correct way to do a non-blocking connect.

I've created a socket descriptor and set O_NONBLOCK for non-blocking IO. I call connect, which returns EINPROGRESS and then I call select, with a timeout value.

How can I tell how long the connect() operation will take before it times out? Can I change this in my program?

If my select operation does time out, what then? Is it normal to close the socket descriptor, create another one, and then retry the connect? Or, is there a way to cancel the connect on the existing socket and retry the operation using the same socket descriptor?

Thanks.

like image 423
DaveR Avatar asked Aug 25 '14 19:08

DaveR


People also ask

How do you set a non-blocking socket in Linux?

To mark a socket as non-blocking, we use the fcntl system call. Here's an example: int flags = guard(fcntl(socket_fd, F_GETFL), "could not get file flags"); guard(fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK), "could not set file flags"); Here's a complete example.

How does a non-blocking socket work?

In blocking socket mode, a system call event halts the execution until an appropriate reply has been received. In non-blocking sockets, it continues to execute even if the system call has been invoked and deals with its reply appropriately later.

How do you accept non-blocking?

What would work well, if possible, is to set the socket to non-blocking mode (using fcntl() and O_NONBLOCK ) from another thread, while the socket is blocked on an accept() call. The expected behaviour is that the accept() call will return with EAGAIN or EWOULDBLOCK in errno .

Is socket connect blocking?

connect() on a TCP socket is a blocking operation unless the socket descriptor is put into non-blocking mode. A successful TCP handshake will be queued to the server application, and can be accept()'ed any time later.


2 Answers

When the connection completes, the socket FD will become writable. You should also check the socket's last error via getsockopt().

How can I tell how long the connect() operation will take before it times out?

You can't, of course. You have to try it. The question doesn't make sense.

Can I change this in my program?

You can change the select timeout, if thats what you mean. If it isn't, i don't understand the question. Note that you can reduce the platform default connect timeout of about a minute by this means, but you can't increase it.

If my select operation does time out, what then?

You close the socket and do whatever your application demands for a connection timeout.

Is it normal to close the socket descriptor, create another one, and then retry the connect?

Only if you have some reason to think you'll get a different result next time.

Or, is there a way to cancel the connect on the existing socket and retry the operation using the same socket descriptor?

No. Once the connect has failed the socket is dead and must be closed.

like image 166
user207421 Avatar answered Oct 11 '22 15:10

user207421


How can I tell how long the connect() operation will take before it times out?

You don't. You have to decide ahead of time what a reasonable timeout will be for your needs, and then pass that value to select(). I typically use anywhere between 5-30 seconds, depending on the type of network my apps are running on.

Can I change this in my program?

Ultimately, no. The OS is in control of how long it waits for the connect to timeout. There may be OS-specific settings you can tweak to govern that timeout, but that would not be portable or recommended.

If my select operation does time out, what then?

The only thing you can do is close the socket and try again.

Is it normal to close the socket descriptor, create another one, and then retry the connect?

Yes.

Or, is there a way to cancel the connect on the existing socket and retry the operation using the same socket descriptor?

No.

like image 41
Remy Lebeau Avatar answered Oct 11 '22 14:10

Remy Lebeau