2011-05-21 66 views
4

我写了两个简单的程序服务器和一个使用C++(Linux)中的套接字的客户机。最初它是一个示例客户端 - 服务器应用程序(回显消息发送和接收答案)。接下来,我更改了客户端以实现HTTP GET(现在我不再使用我的示例服务器)。它可以工作,但是无论我设置了什么缓冲区大小,客户端都只能收到1440字节。我想要整个页面进入缓冲区。我认为这与TCP属性有关,我应该在客户端代码中实现某种循环来捕获答案的所有部分。但我不知道我该做什么。如何通过套接字接收1440多个

这是我的代码:

... 
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是一个缓冲区的大小,我觉得这是绰绰有余了用于测试的相对较小的网页更多。但正如我所提到的,我只收到1440字节。

当服务器的响应大于1440字节时,我可以用recv()函数调用来捕获所有回复“部分”?

在此先感谢。

回答

6

缓冲区大小取决于您控制范围之外的因素(路由器,ADSL链路,IP堆栈等)。传输大量数据的标准方式是重复拨打recv()

+0

是的,其实我预料到了这一点。但是,我怎么知道我应该多少次调用recv()? – 2011-05-21 06:33:46

+1

@ danny_23:直到你有足够的数据。在web服务器的情况下,它会传递给你一个内容长度的头部,它告诉你何时停止读取正文,或者在完成时会关闭套接字,在这种情况下,直到'recv()'返回零。 – 2011-05-21 06:36:29

+0

@ danny_23:反复直到客户告诉你他们已经完成。 – Johnsyweb 2011-05-21 06:36:56

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:),然后您可以继续接收,直到您收到您应该接收的确切字节数。

相关问题