0

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.

donalmg
  • 627
  • 5
  • 15
  • 22
  • Note that the books used to say to do a second `connect()` call in place of `getsockopt(..., SO_ERROR, ...)`; A long time ago. – user207421 May 09 '13 at 00:11

2 Answers2

1

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

donalmg
  • 627
  • 5
  • 15
  • 22
0

I think that socklen_t len = sizeof(error); better than sizeof(int).
It is same result.

DDukDDak99
  • 341
  • 3
  • 12