C语言 如何将套接字重置回阻塞模式(在我将其设置为非阻塞模式之后)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2149798/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:16:36  来源:igfitidea点击:

How to reset a socket back to blocking mode (after I set it to nonblocking mode)?

csocketsnetworkingblockingnonblocking

提问by n179911

I have read this regarding setting a socket to non-blocking mode.

我已经阅读了有关将套接字设置为非阻塞模式的内容。

http://www.gnu.org/software/libc/manual/html_mono/libc.html#File-Status-Flags

http://www.gnu.org/software/libc/manual/html_mono/libc.html#File-Status-Flags

Here is what I did:

这是我所做的:

static void setnonblocking(int sock)
{
    int opts;

    opts = fcntl(sock,F_GETFL);
    if (opts < 0) {
        perror("fcntl(F_GETFL)");
        exit(EXIT_FAILURE);
    }
    opts = (opts | O_NONBLOCK);
    if (fcntl(sock,F_SETFL,opts) < 0) {
        perror("fcntl(F_SETFL)");
        exit(EXIT_FAILURE);
    }
    return;
}

How can I set the socket back to Blocking mode? I don't see a O_BLOCK flag?

如何将套接字设置回阻塞模式?我没有看到 O_BLOCK 标志?

Thank you.

谢谢你。

回答by

Did you try clearing the O_NONBLOCK flag?

您是否尝试清除 O_NONBLOCK 标志?

opts = opts & (~O_NONBLOCK)

回答by EntangledLoops

Here is a more cross-platform capable solution:

这是一个更具跨平台能力的解决方案:

bool set_blocking_mode(int socket, bool is_blocking)
{
    bool ret = true;

#ifdef WIN32
    /// @note windows sockets are created in blocking mode by default
    // currently on windows, there is no easy way to obtain the socket's current blocking mode since WSAIsBlocking was deprecated
    u_long non_blocking = is_blocking ? 0 : 1;
    ret = NO_ERROR == ioctlsocket(socket, FIONBIO, &non_blocking);
#else
    const int flags = fcntl(socket, F_GETFL, 0);
    if ((flags & O_NONBLOCK) && !is_blocking) { info("set_blocking_mode(): socket was already in non-blocking mode"); return ret; }
    if (!(flags & O_NONBLOCK) && is_blocking) { info("set_blocking_mode(): socket was already in blocking mode"); return ret; }
    ret = 0 == fcntl(socket, F_SETFL, is_blocking ? flags ^ O_NONBLOCK : flags | O_NONBLOCK));
#endif

    return ret;
}

回答by eswald

Alternative way to clear the flag:

清除标志的替代方法:

opts ^= O_NONBLOCK;

This will toggle the non-blocking flag, i.e. disable non-blocking if currently enabled.

这将切换非阻塞标志,即如果当前启用则禁用非阻塞。