【问题标题】:When can connect() on O_NONBLOCK socket fail with something other than EINPROGRESS or EALREADY?O_NONBLOCK 套接字上的 connect() 何时会因 EINPROGRESS 或 EALREADY 以外的原因而失败?
【发布时间】:2017-08-24 09:03:18
【问题描述】:

我阅读了以下示例代码,我想知道是否有人能说出 connect() 在哪些平台上可能会因 EINPROGRESS 或 EALREADY 以外的其他原因而失败。

失败是指执行示例中的else 分支以执行。源代码中的评论建议使用 FreeBSD。有没有其他系统?我无法让它在 Linux 上失败。

        if (connect(hostp->sockets[i],
            (struct sockaddr *)res->ai_addr,
            res->ai_addrlen) == -1) {
            /* This is what we expect. */
            if (errno == EINPROGRESS) {
                printf("    connect EINPROGRESS OK "
                    "(expected)\n");
                FD_SET(hostp->sockets[i], &wrfds);
            } else {
                /*
                 * This may happen right here, on
                 * localhost for example (immediate
                 * connection refused).
                 * I can see that happen on FreeBSD
                 * but not on Solaris, for example.
                 */
                printf("    connect: %s\n",
                    strerror(errno));
                ++n;
            }
        [...]

来源:http://mff.devnull.cz/pvu/src/tcp/non-blocking-connect.c

【问题讨论】:

    标签: sockets unix posix portability errno


    【解决方案1】:

    连接失败的原因有很多。正如评论正确地所说,如果没有监听服务器,在某些平台上连接到 localhost 时,即使是非阻塞连接也可能会立即失败。如果无法确定到目标​​的路由,例如默认路由的接口已关闭,则连接通常会立即失败。然后还有其他失败的原因,例如内存不足、在沙箱中运行时拒绝连接或类似情况。

    【讨论】:

    • 接口关闭听起来很有希望。接下来我会试试这个。 (我正在处理我认为不能正确处理这些故障的代码,我想写下实际的复制步骤,这将使它泄漏文件描述符(如果我能以正确的方式触发故障,就会发生这种情况)。
    • 我无法让它立即失败(或成功)。我尝试了 linux、freebsd 和 openindiana(三心二意)。尽管如此,不处理代码中的可能性绝对是一个错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    • 2020-10-28
    • 1970-01-01
    相关资源
    最近更新 更多