read()会在select()之后阻塞吗?

Bas*_*evs 18 sockets linux

我正在通过TCP/IP套接字读取数据流.流负载非常不均匀.有时大量的数据每秒都会到达,有时一小时内没有数据.在长时间不活动期间(没有来自远程服务器的数据,但连接仍在线),我的程序应采取一些措施.

我正在使用select()实现超时.它告诉我是否有数据准备就绪,但我不知道究竟能读多少而不会导致read()阻塞.阻塞是不可接受的,因为它可能比我需要的超时时间长得多.

为了提高效率,将流读入大缓冲区,并使用该缓冲区大小提供read()调用.

如果要填充的缓冲区大于套接字中现有的可用数据量,那么read()会在select()之后阻塞吗?

Dam*_*mon 17

实际上它不应该阻塞(这就是select()的用途!),但事实上,它可能是异常的.通常,read()应该返回到你指定的最大字节数,这可能包括零字节(这实际上是一个有效的事情发生!),但它应该在之前报告准备就绪之后永远不会阻塞.

不过,请参阅Linux select手册页:

在Linux下,select()可以将套接字文件描述符报告为"准备好读取",而不是后续的读取块.这可能例如在数据到达时发生但在检查时具有错误的校验和并被丢弃.可能存在其他情况,其中虚假地报告文件描述符为就绪.因此,在不应阻塞的套接字上使用O_NONBLOCK可能更安全.

  • 顺便说一下,我在[linux-kernel list](https://lkml.org/lkml/2011/6/18/105)上询问了Linux select()行为,得到了Alan Cox的好评. (4认同)