如何通过套接字接收超过1440的数据量

4
我用C++(Linux)编写了两个简单的程序,一个服务器和一个客户端,使用套接字。最初它是一个示例客户端-服务器应用程序(回显消息发送和接收答案)。接下来,我更改了客户机以实现HTTP GET(现在不再使用我的示例服务器)。它可以工作,但无论我设置多大的缓冲区,客户端仅接收到1440个字节。我想将整个页面接收到缓冲区中。我认为这与TCP属性有关,我应该在客户端代码中实现一些循环来捕获答案的所有部分。但我不知道我应该做什么。这是我的代码:
...
int bytesSent = send(sock, tmpCharArr, message.size()+1, 0);
// Wait for the answer. Receive it into the buffer defined.
int bytesRecieved = recv(sock, resultBuf, 2048*100, 0);
...

2048 * 100 是缓冲区大小,我认为这对于用于测试的相对较小的 WEB 页面已经足够了。但是,正如我所提到的,我只收到了 1440 字节。
当服务器响应大于 1440 字节时,我该如何使用 recv() 函数调用来捕获所有的回复“部分”?
提前感谢。
2个回答

6

缓冲区大小由你无法控制的因素(路由器、ADSL链接、IP堆栈等)决定。传输大量数据的标准方式是重复调用recv()


是的,实际上我预料到了这一点。但是我怎么知道应该调用recv()多少次? - danny_23
1
@danny_23:直到你有足够的数据。对于Web服务器,它要么传递一个内容长度头,告诉你何时停止读取正文,要么在完成时关闭套接字,在这种情况下,只需继续读取,直到recv()返回零。 - Marcelo Cantos
@danny_23: 重复执行,直到客户告诉你他们已经完成。 - johnsyweb

1

HTTP是基于TCP协议的,为了更好地理解TCP套接字的工作原理,您需要将它们视为流而不是数据包。

为了进一步明确,阅读我之前的帖子:使用Flash套接字重新组合拆分的TCP数据包

至于为什么您只收到1400(左右)字节,您必须了解MTU和分段。简而言之,MTU(最大传输单元)是网络传输单个数据包的最大大小能力。整个网络的MTU是涉及的所有路由器中最低的MTU。如果您尝试发送大于该网络MTU的单个数据包,则会进行分段。

为了更好地理解MTU和分段,请阅读:http://www.miislita.com/internet-engineering/ip-packet-fragmentation-tutorial.pdf

现在讨论如何在缓存中接收整个页面,一种替代方案是保持调用recv()并将您在缓冲区中获得的数据附加到其中,直到recv()返回。这将有效,因为通常Web服务器会在发送响应后关闭TCP连接。然而,如果Web服务器没有关闭会话(可能配置了keep-alive),则此技术将无法正常工作。

因此,正确的解决方案是保持接收直到您接收到HTTP标头。查看并确定整个HTTP响应的长度(Content-Length:),然后可以继续接收,直到您接收到应该接收的确切字节数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接