首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非阻塞connect()和EINTR

非阻塞connect()和EINTR
EN

Stack Overflow用户
提问于 2013-02-20 23:15:42
回答 1查看 1.9K关注 0票数 1

我使用的是来自史蒂文斯的connect_nonb(),UNIX网络编程:

代码语言:javascript
复制
int
connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec)
{
    int                     flags, n, error;
    socklen_t               len;
    fd_set                  rset, wset;
    struct timeval  tval;

    flags = Fcntl(sockfd, F_GETFL, 0);
    Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

    error = 0;
    if ( (n = connect(sockfd, saptr, salen)) < 0)
            if (errno != EINPROGRESS)
                    return(-1);

    /* Do whatever we want while the connect is taking place. */

    if (n == 0)
            goto done;      /* connect completed immediately */

    FD_ZERO(&rset);
    FD_SET(sockfd, &rset);
    wset = rset;
    tval.tv_sec = nsec;
    tval.tv_usec = 0;

    if ( (n = Select(sockfd+1, &rset, &wset, NULL,
                                     nsec ? &tval : NULL)) == 0) {
            close(sockfd);          /* timeout */
            errno = ETIMEDOUT;
            return(-1);
    }

    if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
            len = sizeof(error);
            if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
                    return(-1);                     /* Solaris pending error */
    } else
            err_quit("select error: sockfd not set");

done:
    Fcntl(sockfd, F_SETFL, flags);  /* restore file status flags */

    if (error) {
            close(sockfd);          /* just in case */
            errno = error;
            return(-1);
    }
    return(0);
}

此函数允许自定义connect()的超时。如果在select()中阻塞等待连接成功时接收到信号,select()将以-1 (EINTR)退出。此时,select()超时尚未到期,连接未成功(即目标主机可能已断开连接),但随后的getsockopt()不会返回错误。

getsockopt()是否应该返回一个错误,或者史蒂文斯代码是否应该检查select()的返回码(和errno)?

目前,当连接到一个不存在的主机并且一个信号中断select()时,这个函数错误地返回成功。

EN

回答 1

Stack Overflow用户

发布于 2013-02-21 02:55:45

我不确定Select()是什么。我假设它只是对select()进行了某种简单的包装。

在大多数应用程序中,每当select()使用EINTR失败时,您应该静默地循环并再次调用select(),可能是在重新计算超时之后,以说明在先前对select()的调用中已经经过了一段时间。

这种情况也不例外。select()应该在循环中。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14983335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档