为啥套接字不设置为非阻塞模式?

Posted

技术标签:

【中文标题】为啥套接字不设置为非阻塞模式?【英文标题】:Why socket does not set to non blocking mode?为什么套接字不设置为非阻塞模式? 【发布时间】:2013-04-24 06:26:43 【问题描述】:

我尝试使用ioctlsocket 将我的套接字设置为非阻塞模式,但它返回-1WSAGetLastError 返回10045 - 不支持操作。为什么会这样?

我写的代码比较具体,因为它不是 C++,而是带有外语接口的 Lisp(它允许从 dll 中调用 C 和 C++ 函数),但实际上没关系,因为其他一切都可以工作。

代码如下:

(defconstant FIONBIO #x5421)
(setf socket-descriptor (socket AF_INET SOCK_STREAM IPPROTO_TCP))
...
(fli:with-dynamic-foreign-objects ((no-block (:unsigned :long) :initial-element 1))
  (ioctlsocket socket-descriptor FIONBIO no-block))
...

socket-descriptor - 只是一个套接字描述符,使用标准函数socket创建

FIONBIO - 一个常数,我通过谷歌搜索发现它的价值

no-block - 指向u_long 的指针,u_long 的值为1

ioctlsocket 返回 -1,WSAGetLastError 返回 10045。

【问题讨论】:

【参考方案1】:

如果有帮助,您从WSAGetLastError 得到的错误 10045 描述如下:

编辑 在我的 Windows 系统上,我在调试器中检查了FIONBIO 的值,它应该是0x8004667E

在 Windows 8 SDK 的 winsock.hwinsock2.h 中都是这样定义的:

#define _IOW(x,y,t)  (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define FIONBIO      _IOW('f', 126, u_long) /* set/clear non-blocking i/o */

如果您将unsigned int 设置为等于FIONBIO,那么您将得到0x8004667E

【讨论】:

谢谢,我已经阅读了这篇文章,但我仍然不知道出了什么问题。 是的,这是一个典型的“有用”的 MS 描述 - 但它似乎表明在您可以将其设置为非阻塞之前有一些套接字属性或状态是必需的。如果我能找到更多线索,我会更新答案。 天啊,非常感谢,它有效!我知道 FIONBIO 可能不正确,但找不到另一个可能的值。 "我在调试器中检查了FIONBIO的值,应该是0x8004667E"。这几乎是不可能的。这将是一个单比特值。 @EJP - 刚刚在编辑中澄清了我的来源,这可能不太可能,但这就是它的定义方式并且解决了 OP 的问题。这只是 Winsock 的事情吗?

以上是关于为啥套接字不设置为非阻塞模式?的主要内容,如果未能解决你的问题,请参考以下文章

为啥非阻塞套接字在connect() 或accept() 之前是可写的?

设置非阻塞的套接字Socket

如何将 TCP 套接字更改为非阻塞?

自己做的类库 封装socket类 请问怎样实现非阻塞模式

套接字:为啥阻塞 read() 会因 ENOTCONN 而失败?

如果在超时发生之前没有收到数据,Python 的 socket.recv() 会为非阻塞套接字返回啥?