如何确定套接字是否已在Windows中处于非阻止模式?

时间:2010-10-20 01:54:59

标签: c windows sockets

有没有办法确定套接字是否已在Windows中处于非阻止模式?

我知道这可以在Linux的情况下完成,但是,我无法找到适用于此Windows的任何方法。

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

3 个答案:

答案 0 :(得分:4)

您可以检查此问题的唯一方法是在非阻塞套接字上执行非法操作并检查其是否以预期方式失败。几乎没有最强大的设计。

套接字将被阻止,除非您使用WSAIoctlioctlsocket使用FIONBIO明确将其设置为非阻止。我想,这对于检查代码来说不是太难。如果你必须在运行时跟踪这个问题,那么@jweyrich建议的每个套接字的标记就是你的选择。

答案 1 :(得分:1)

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

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

否则,您可以在套接字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;
}

答案 2 :(得分:0)

从MSDN,connect()的返回值:

  • 阻止套接字上,返回值表示连接尝试成功或失败。

  • 使用非阻塞套接字,无法立即完成连接尝试。在这种情况下,连接将返回SOCKET_ERRORWSAGetLastError()将返回WSAEWOULDBLOCK