当使用 read(2)
和阻塞 I/O 从套接字读取时,我什么时候知道另一端(客户端)没有更多数据要发送? (“没有更多数据要发送”的意思是,例如,客户端正在等待响应)。起初,我认为当 read
返回的字节数小于 count
时就达到了这一点(如 read(fd, *buf, count)
).
但是如果客户端发送的数据是碎片化的怎么办?阅读直到 read
返回 0
将是一个解决方案,但据我所知 0
仅在客户端关闭连接时返回 - 否则, read
只会阻塞,直到连接关闭。我考虑过使用非阻塞 I/O 和 select(2)
的超时,但这对我来说似乎不是一个整洁的解决方案。
是否有任何已知的最佳实践?
最佳答案
“另一方没有更多数据可发送”的概念,在传输数据中没有超时或某些语义,是毫无意义的。通常,客户端/服务器上的代码处理数据的速度要比网络传输数据的速度快。因此,如果当您尝试 read()
时接收缓冲区中没有数据,这仅意味着网络尚未尚未传输所有内容,但您没有办法判断下一个数据包是否会在一毫秒、一秒或一天内到达。您可能会认为第一种情况是“有更多数据要发送”,第三种情况是“没有更多数据要发送”,第二种情况取决于您的应用程序。
如果对方不关闭连接,您可能也不知道它何时准备好发送下一个数据包。
因此,除非您对客户端发送的内容有特定的语义和知识,否则最好使用 select() 和非阻塞 I/O。
在特定情况下,可能还有其他方式 - 例如,如果您知道客户端将每隔 n 秒发送 XML 标记、一些数据和结束标记。在这种情况下,您可以在收到最后一个数据包后 n 秒开始阅读,然后继续阅读直到收到结束标记。但正如我所说,这不是通用方法,因为它需要 channel 上的语义。
关于c - 使用阻塞 I/O 通过套接字读取所有可用字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22010139/