有没有办法找出一个套接字是否已经在Windows中的非阻塞模式?
我知道这可以在Linux的情况下,但是,我无法find任何方式,这个Windows。
我所有的编码都是“C”语言。 有没有办法?
唯一可以检查的方法是在非阻塞套接字上执行一些非法的操作,并检查它是否以预期的方式失败。 几乎没有最强大的设计。
套接字将被阻塞,除非您使用WSAIoctl或带有FIONBIO
将其明确设置为非阻塞。 这不能太难检查你的代码,我会想。 如果你必须在运行时跟踪这个,@ jweyrich建议的每个套接字的标志是要走的路。
从MSDN, connect()的返回值:
在阻塞套接字上,返回值指示连接尝试成功或失败。
使用非阻塞套接字时,连接尝试不能立即完成。 在这种情况下,连接将返回SOCKET_ERROR
,并且WSAGetLastError()
将返回WSAEWOULDBLOCK 。
刚刚在这里回答了同样的问题,所以这里有一个复制粘贴,希望它有助于:
以前,您可以调用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; }