select() returns and indicates writability before a non-blocking TCP socket has actually connected.
- From: jaswantv@xxxxxxxxxxxxxxxxxx
- Date: 25 Oct 2006 09:09:06 -0700
Hi,
Thanks in advance for taking a little time to read this.
I am trying to implement a TCP client which can wait until it has a
server to connect to. The idea is that the client will emit periodic
notifications while the server is unavailable. I have used non-blocking
sockets and select() to implement the behaviour where each call to
select() will return if either the connection is made (server starts up
and begins accepting connections) or the timeout expires. If a timeout
occurs, the socket is closed and a new socket along with a new call to
connect() is done.
I have noticed that on Linux select() returns instantly with the
correct FD bit set (indicating the socket is available for writing).
Only when I check the socket options (SO_ERROR) do I find that the
connection has not been made. I have tried the same code on Solaris and
the select() waits until the connection has been made or the timeout
expires.
I would like to know if the above is deemed correct behaviour under
Linux.
As I mentioed, the function containing this code is being called while
in a loop. The socket is made non-blocking just prior to the connect().
You can see that I initialise the FD sets and the timeout prior to each
call to select(). Here is the code:
int connectRC;
connectRC=connect(socketId,(struct sockaddr
*)&socketAddress,sizeof(socketAddress));
if (connectRC<0)
{
if (errno!=EINPROGRESS)
{
// error handling removed to shorten example
}
}
/*
* Add socket to the FileDescriptor set to be used by select
*/
fd_set fdWriteSet;
FD_ZERO(&fdWriteSet);
FD_SET(socketId,&fdWriteSet);
/*
* Setup the timeout structure
*/
struct timeval selectTimeout;
selectTimeout.tv_sec=timeout; // default value of 2 seconds
selectTimeout.tv_usec=0;
/*
* Call non-blocking select() to wait on the socket for a
connection or until the timeout expires
*/
int selectRC;
selectRC=select(socketId+1,NULL,&fdWriteSet,NULL,&selectTimeout);
if (selectRC<0)
{
// error handling removed to shorten example
}
if (FD_ISSET(socketId,&fdWriteSet)==0)
{
// error handling removed to shorten example
}
int getsockoptRC;
int sockErr;
int sockErrLen=sizeof(int);
getsockoptRC=getsockopt(socketId,SOL_SOCKET,SO_ERROR,(int*)&sockErr,&sockErrLen);
if (getsockoptRC<0)
{
// error handling removed to shorten example
}
if (sockErr!=0)
{
// error handling removed to shorten example
// CODE ALWAYS FAILS HERE
}
FD_CLR(socketId,&fdWriteSet);
Thanks again,
Jas.
.
- Prev by Date: Re: HTTPD : SLOW all http connections
- Next by Date: Re: HTTPD : SLOW all http connections
- Previous by thread: Question on public WIFI access points
- Next by thread: simple connections between my boxes ?
- Index(es):
Relevant Pages
|