Next
Previous
Contents
From Andrew Gierth (
ndrew@erlenstar.demon.co.uk):
Technically, fcntl(soc, F_SETFL, O_NONBLOCK) is incorrect since it
clobbers all other file flags. Generally one gets away with it since
the other flags (O_APPEND for example) don't really apply much to
sockets. In a similarly rough vein, you would use fcntl(soc, F_SETFL,
0) to go back to blocking mode.
To do it right, use F_GETFL to get the current flags, set or clear the
O_NONBLOCK flag, then use F_SETFL to set the flags.
And yes, the flag can be changed either way at will.
Andrew Gierth (
ndrew@erlenstar.demon.co.uk) has outlined the
following procedure for using select() with connect(), which will
allow you to put a timeout on the connect() call:
First, create the socket and put it into non-blocking mode, then call
connect(). There are three possibilities:
- connect succeeds: the connection has been successfully made (this
usually only happens when connecting to the same machine)
- connect fails: obvious
- connect returns -1/EINPROGRESS. The connection attempt has begun,
but not yet completed.
If the connection succeeds:
- the socket will select() as writable (and will also select as
readable if data arrives)
If the connection fails:
- the socket will select as readable *and* writable, but either a
read or write will return the error code from the connection
attempt. Also, you can use getsockopt(SO_ERROR) to get the error
status - but be careful; some systems return the error code in the
result parameter of getsockopt(), but others (incorrectly) cause
the getsockopt call itself to fail with the stored value as the
error.
Sample code that illustrates this can be found in the socket-faq
examples, in the file connect.c.
Next
Previous
Contents