我想知道以下情况是否真实?!
- 在非阻塞TCP套接字上调用select() (读操作) 表明套接字已准备就绪
- 随后的recv() 调用返回EWOULDBLOCK,尽管已经调用了select()
recv()
函数将返回EAGAIN
而非EWOULDBLOCK
,这是可能的。因为你刚才使用了select()
进行了查询,所以以下两种情况之一发生:
select()
和recv()
之间处理了输入缓冲区。这是可能的,但只有在多个线程/进程尝试从同一套接字读取时才会出现。
O_NONBLOCK
TCP套接字,特别是在回环接口上运行时,有时会在select()
报告套接字准备好读取后从recv()
返回EAGAIN
。在我的情况下,在另一端半关闭发送流之后发生这种情况。
更多详情请参阅我的OCaml网络应用程序环境分发中NX库中的t_nx.ml
源代码。(链接)
是的,这是真实的。以下是它发生的一种方式:
TCP协议的未来修改将添加一方有能力“撤销”其发送的信息(前提是另一方的应用层尚未接收到该信息)。此功能在连接时进行协商。另一方向您发送一些数据,您获得一个select
命中。在您调用recv
之前,另一方使用此新扩展“撤销”数据。您的read
因没有可读取的数据而出现“would block”错误。
select
函数是一种状态报告函数,不提供未来保证。假设现在对select
的命中确保后续操作不会阻塞,就像以任何其他状态报告函数的方式使用一样是无效的。这与使用access
尝试确保由于权限不正确而导致后续操作不会失败或使用statfs
尝试确保后续写入不会因磁盘已满而失败一样糟糕。
在多线程环境中,两个线程从套接字读取数据是可能的。这是一个多线程应用程序吗?
select()
的参数?如果超时发生在 select()
和 recv()
之间怎么办? - dwc