使用Berkeley套接字的recv()未知大小的数据

时间:2011-10-16 03:57:37

标签: http sockets timeout recv

我有一个C ++代码,我使用Berkeley套接字中的recv()来接收来自远程主机的数据。问题是我不知道数据的大小(这是可变的)所以我需要某种超时选择(可能)来使这项工作。

由于我是套接字编程的新手,我想知道例如Web客户端如何处理来自服务器的响应(例如服务器将html数据发送到客户端)。它是否使用某种超时,因为它不知道页面有多大?与FTP客户端相同。

1 个答案:

答案 0 :(得分:4)

当您的数据长度可变时,通常该数据将在另一个容器中构建。也就是说,在实际数据块之前有一个标题告诉接收者它应该接受多少数据。

例如,HTTP使用换行符来分隔数据。如果有可变长度的消息,那么在标题中它将包含“Content-length:”字段,该字段指示一旦接收到整个标题就准确读取多少字节(当您读取2个连续的新行时标题停止)。

从套接字读取4个字节,获取多少数据,然后再做另一个接收并读取其余数据,这是完全正常的。只是要小心,当你要求4个字节时,套接字可能会给你1-4个字节之间的任何地方,所以小于4意味着你需要返回并要求剩下几个字节。这是一个非常常见的错误。在开发环境中,当你要求4时,你几乎总会得到4个字节,但是一旦你部署你的应用程序,在某个机器的某个地方,你会得到随机崩溃,因为它们的网络行为有些不同。

通常,依靠超时来确定何时到达数据末尾是一种糟糕的方法。如果超时,您可能会在一个控制良好的开发环境中“可靠地”工作,但这是一个非常不稳定的解决方案。任何CPU /磁盘/网络连接都可能导致您的应用程序过早停止接收。您还限制了数据吞吐量和响应速度,因为您的应用程序正在休眠一段时间而不是工作。