Reputation: 655
I have setup a timeout on a non-blocking connect call, which timesout correctly when the connection is attempted to an address that will not respond. However, when the connection is refused by the destination, it does not seem to return the connection refused call.
int x = fcntl(iSock,F_GETFL, 0);
fcntl(iSock,F_SETFL, x | O_NONBLOCK);
fd_set writeFD;
FD_ZERO(&writeFD);
FD_SET(iSock, &writeFD);
timeval timeout;
timeout.tv_sec = 30;
timeout.tv_usec = 0;
errno = 0;
if ((iStat = connect(iSock, (struct sockaddr *)&addr, sizeof(addr))) < 0)
{
if(errno == EINPROGRESS)
{
if(int retval = (select (iSock+1, (fd_set *)NULL, &writeFD, (fd_set *)NULL, (struct timeval *)(&timeout)) > 0) )
{
socklen_t len = 0;
int error = 0;
if (getsockopt(iSock, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
return (-1);
if (error == EINPROGRESS)
{
close(iSock);
errno = error;
return (-1);
}
else
{
printf("Connected \n");
return 0;
}
}
else
{
printf("Not Connected - %d\n", errno);
close(iSock);
return iStat;
}
}
else
{
close(iSock);
return iStat;
}
}
From the connect call, it always seems to return EINPROGRESS, then the select call will return > 0 with error set as 0.
When I change this to a blocking connect call, I get the return code of CONNECTIONREFUSED immediately from the connect call.
Upvotes: 0
Views: 3817
Reputation: 361
I think that socklen_t len = sizeof(error);
better than sizeof(int)
.
It is same result.
Upvotes: 0
Reputation: 655
The socklen_t len = 0; is incorrect. This needs to be set to socklen_t len = sizeof(int);
Setting this value fixed the issue, and the correct return code (CONNREFUSED) was set from the select call
Upvotes: 1