非阻塞连接呼叫不会返回拒绝连接

时间:2013-05-08 12:25:50

标签: linux sockets tcp nonblocking

我在非阻塞连接调用上设置了超时,当尝试连接到不响应的地址时,会超时。 但是,当目的地拒绝连接时,它似乎不会返回拒绝连接呼叫。

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;
    }
}

从连接通话中,它似乎总是返回EINPROGRESS,然后选择通话将返回&gt; 0,错误设置为0。

当我将其更改为阻塞连接呼叫时,我立即从连接呼叫中获得CONNECTIONREFUSED的返回码。

2 个答案:

答案 0 :(得分:1)

socklen_t len = 0;是不正确的。 这需要设置为     socklen_t len = sizeof(int);

设置此值可解决问题,并且从select调用中设置了正确的返回码(CONNREFUSED)

答案 1 :(得分:0)

我认为socklen_t len = sizeof(error);优于sizeof(int) 结果相同。