c - 使用阻塞 I/O 通过套接字读取所有可用字节

标签 c linux sockets bsd

当使用 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/

相关文章:

c - 未正确声明数组检测到堆栈粉碎错误

c++ - Winsock 程序收到 400 错误请求,您的浏览器发送了该服务器无法理解的请求

java - 为 SSLSocket 握手设置超时

c - 警告 TokenList 类型转换

c - 从同一进程发送和接收UDP数据包

将 uint32_t 转换为 int32_t 并随后比较它们

linux - Linux 中 'erase block' 实用程序中的 `mkfs.jffs2' 是什么?

python - 将 linux sha512 影子转换为十六进制

php - 安装 curl 扩展后 php 停止工作

java - 通过套接字发送 XMLEncoded SOAP 请求导致无法创建信封