如何通过套接字接收超过1440

时间:2011-05-21 06:24:46

标签: c++ linux sockets

我在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 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:1)

HTTP通过TCP工作,为了更好地理解TCP套接字的工作,你必须将它们视为流而不是数据包。

为了进一步说明,请阅读我之前的帖子:recombine split TCP packet with flash sockets

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

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

现在关于如何在缓冲区中接收整个页面,另一种方法是继续调用recv()并将您获得的数据附加到缓冲区中,直到recv()返回zero。这将起作用,因为通常Web服务器在向您发送响应后将关闭TCP连接。但是,如果Web服务器没有关闭会话(可能是保持活动配置),这种技术将无法工作。

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