代码之家  ›  专栏  ›  技术社区  ›  Jay

如何在Windows中找出套接字是否已经处于非阻塞模式?

  •  4
  • Jay  · 技术社区  · 14 年前

    在Windows中,是否有方法确定套接字是否已经处于非阻塞模式?

    我知道在Linux的情况下可以这样做,但是,我找不到任何方法来使用这个窗口。

    我所有的编码都是“C”语言。有办法吗?

    3 回复  |  直到 9 年前
        1
  •  3
  •   Steve Townsend    14 年前

    唯一可以检查的方法是在非阻塞套接字上执行非法操作,并检查它是否以预期的方式失败。几乎不是最坚固的设计。

    除非使用 WSAIoctl ioctlsocket 具有 FIONBIO . 我想,这不可能太难签入您的代码。如果您必须在运行时跟踪它,那么按@jweyrich的建议为每个套接字设置一个标志是可行的。

        2
  •  1
  •   EntangledLoops    9 年前

    刚刚回答了同样的问题 here 所以这里有一个复制粘贴,希望它有帮助:

    以前,你可以打电话 WSAIsBlocking 以确定这一点。如果您正在管理遗留代码,这可能仍然是一个选项。

    否则,您可以在socket api上编写一个简单的抽象层。由于默认情况下所有套接字都是阻塞的,所以您可以维护一个内部标志,并通过API强制所有套接字操作,以便始终了解状态。

    下面是一个跨平台的代码片段,用于设置/获取阻塞模式,尽管它不能完全满足您在Windows上的需要:

    /// @author Stephen Dunn
    /// @date 10/12/15
    bool set_blocking_mode(const 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 flags = is_blocking ? 0 : 1;
        ret = NO_ERROR == ioctlsocket(socket, FIONBIO, &flags);
    #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;
    }
    
        3
  •  0
  •   Vantomex    14 年前

    从msdn返回 connect() :

    • 在一 舞台调度 socket,返回值表示连接尝试成功或失败。

    • 用一个 非阻塞 套接字,无法立即完成连接尝试。在这种情况下,Connect将返回 SOCKET_ERROR WSAGetLastError() 将返回 WSAEWOULDBLOCK .