C 的基本非阻塞 tcp 连接示例

Basic non blocking tcp connect example for C

我很难理解无块套接字以及如何将它们用于网络扫描仪。据我所知,我应该做的是通过以下方式将套接字设置为非阻塞:

fcntl(sockfd , F_SETFL, O_NONBLOCK);

然后只需调用应该 return EINPROGRESS 的连接。 然后我应该像这样使用 select:

if (select(sockfd  + 1, NULL, &fdset, NULL, &tv) == 1)

其中 tv 是时间结构的地址。

然后

getsockopt(sockfd , SOL_SOCKFD ET, SO_ERROR, &so_error, &len);

知道操作是否成功,但它总是正确的。

这里有人能给我一个小的 c 程序的例子吗 检查 ip 是否启动,解释整个事情? 我真的不知道该怎么做。

SO_ERROR returns 套接字的最后一个错误代码并重置它。如果 select() 报告套接字可写,则连接成功,无需检查错误代码。如果 select() 报告超时,连接仍在进行中,因此错误代码仍将是 EINPROGRESS,只需关闭套接字并继续。要检测连接失败,请将套接字放入 select()exceptfds 参数中的 fd_set,然后仅当仍然设置 fd_set 时才检查 SO_ERRORselect() returns > 0.

fcntl(sockfd, F_SETFL, O_NONBLOCK);

res = connect(sockfd, ...);
if (res == -1)
{
    if (errno != EINPROGRESS)
    {
        // connect failed, do something...
        return;
    }

    fd_set wfd, efd;

    FD_ZERO(&wfd);
    FD_SET(sockfd, &wfd);

    FD_ZERO(&efd);
    FD_SET(sockfd, &efd);

    timeval tv;
    ...

    res = select(sockfd+1, NULL, &wfd, &efd, &tv);
    if (res == -1)
    {
        // select failed, do something...
        close(sockfd);
        return;
    }

    if (res == 0)
    {
        // connect timed out...
        close(sockfd);
        return;
    }

    if (FD_ISSET(sockfd, &efd))
    {
        // connect failed, do something...
        getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &len);
        close(sockfd);
        return;
    }
}

// connected !