我有一个 C++ 代码,其中我使用 Berkeley Sockets 的 recv() 从远程主机接收数据。问题是我不知道数据的大小(它是可变的),所以我需要某种超时选项(可能)来完成这项工作。
由于我是套接字编程的新手,我想知道例如 Web 客户端如何处理来自服务器的响应(例如,服务器将 html 数据发送到客户端)。它是否使用某种超时,因为它不知道页面有多大?与 FTP 客户端相同。
当您的数据具有可变长度时,通常该数据被框在另一个容器中。也就是说,在实际数据块之前有一个标头,告诉接收器它应该接受多少数据。
例如 HTTP 使用换行符来分隔数据。如果有可变长度消息,那么在标题中它将包含“Content-length:”字段,该字段指示接收到整个标题后要读取的确切字节数(当您读取 2 个连续的新行时标题停止)。
从套接字读取 4 个字节,获取随后的数据量,然后再进行一次接收并读取其余部分,这是完全可以的。请注意,当您请求 4 个字节时,套接字可能会给您 1-4 个字节之间的任何值,因此小于 4 的任何内容都意味着您需要返回并请求剩余的几个字节。这是一个非常常见的错误。在开发环境中,当请求 4 时,您几乎总是会得到 4 个字节,但是一旦您部署了应用程序,在某些机器上的某个地方,您会随机崩溃,因为它们的网络行为有所不同。
通常,依靠超时来确定何时到达数据末尾是一种不好的方法。使用超时,您可能会在控制良好的开发环境中“可靠地”工作,但这是一个非常不稳定的解决方案。任何 CPU/磁盘/网络故障都可能导致您的应用过早停止接收。您还限制了数据吞吐量和响应能力,因为您的应用程序在一段时间内处于休眠状态而不是在工作。