timeout on connect

Hallo

How can a timeout be specified for the connect() call? There are cases where
a program hangs for quite a long time which could lead to undesired system
state.

Thanks a lot
Markus

Markus Jauslin <markus.jauslin@ch.mullermartini.com> wrote:

How can a timeout be specified for the connect() call? There are cases where
a program hangs for quite a long time which could lead to undesired system
state.

Markus

You can either use an alarm before the connect call and setup a handler with
sigaction() to catch the alarm; connect will return EINTR. Or you can use
fcntl() to make the socket non-blocking and use select() if connect fails:

Below is a function I use for this. I use this in an X application, with a
callback on write-accessibility on the socket, but you could use select() (on
write/error). In the callback, I use the callback code also shown to make
sure the connection is up.

Hope this helps.

static int
connect_to_server( char * server_name, int port, int nonblocking, int quiet )
{
struct sockaddr_in sin;
struct hostent * hp;
int fd;
int status;

errno = 0; // gethostbyname() doesn’t always set errno
hp = gethostbyname( server_name );

if ( hp == NULL )
{
if (!errno) syslog( LOG_ERR, “Unknown host: %s”, server_name );
else syslog( LOG_ERR, “Unknown host: %s: %m”, server_name );
return -1;
}

if ( ( fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )) < 0 )
{
syslog( LOG_ERR, “socket: %m” );
return -1;
}

sin.sin_family = AF_INET;
sin.sin_port = htons( port );

bcopy( hp->h_addr, &sin.sin_addr.s_addr, hp->h_length );

if (( nonblocking ) && ( fcntl( fd, F_SETFL, O_NONBLOCK ) == -1 ))
{
syslog( LOG_ERR, “fcntl(O_NONBLOCK): %m” );
return -1;
}

status = connect( fd, (struct sockaddr *) &sin, sizeof sin );

// if we are connecting non-blocking, the connection may not yet be complete
// and we get an EINPROGRESS error from connect(). A select() on write call
// can be used (by caller) to tell when the connection is complete
if ( status < 0 )
{
if ( nonblocking && (( errno == 0 ) || ( errno == EINPROGRESS )))
status = 0;
else
{
close( fd );
fd = -1;
if ( !quiet )
syslog( LOG_ERR, “connect(%s): %m”, server_name );
}
}
return fd;

} // _connect_to_server()


Callback code …

int connection_status;
int len = sizeof( connection_status );

if ( getsockopt( fd, SOL_SOCKET, SO_ERROR,
&connection_status, &len ) < 0 )
{
close( fd );
syslog( LOG_ERR, “async socket error: %m” );
return;
}

if ( connection_status != 0 )
{
close( fd );
return;
}

// Socket is connected … continue


William Morris
wrm@innovation-tk.com