【问题标题】:Why actual bytes read from server's response less than the Content-Length?为什么从服务器响应中读取的实际字节小于 Content-Length?
【发布时间】:2012-03-05 15:52:53
【问题描述】:

我正在 Linux 3.0 内核中用 C 语言编写代理。代理将来自浏览器的请求转发到目标服务器并从服务器读取响应。

这是一个请求:

GET http://www.yongchuan.org/ HTTP/1.1
Host: www.yongchuan.org
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Proxy-Connection: keep-alive

这是代理读取的一个响应:

HTTP/1.1 200 OK
Content-Length: 3170
Content-Type: text/html
Content-Location: http://www.yongchuan.org/index.html
Last-Modified: Fri, 22 Jul 2011 01:28:50 GMT
Accept-Ranges: bytes
ETag: "72d9d7b5e48cc1:1a73"
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Date: Sun, 04 Mar 2012 16:26:05 GMT

<html>

<head>

..............

<tr> 
  <td width="43%" ></td>
  <td width="46%"></td>
</tr>
<tr>
  <td width="43%"><img src="images/triangle.gif"> ��ѧ�ڿγ̣�<a href="jiangyi/yytl/2007(a)/yytl.htm">Ӧ��ͼ��</a></td>
  <td width="46%" ><img src=

问题是,代理读取的实际字节大小为 2880,数据突然结束,远小于 Context length: 3170。

我的代码如下:

241 int readlen;
242 char buffer[128 * 4096];
243 do { 
244     readlen = read(servfd, buffer, 128 * 4096);
245     printf("readlen:%d\n", readlen);
246     if( readlen < 0 ) {
247         perror("read() from server failed");
248     }   
249     printf("read content:\n%s", buffer2);
250     write(cliefd, buffer, readlen);
251 } while( readlen == 128 * 4096 );

这里 servfd 是到服务器的套接字,cliefd 是到客户端的套接字。 可能的原因是什么?谢谢!

【问题讨论】:

  • 我认为您编写的代理不是在内核 3.0 中,而是 for 内核 3.0;您的代理是在内核之外运行的用户级应用程序(并且不时向内核发出系统调用)。在 Linux 内核内部编写代理代码会很疯狂(例如一个怪物模块);考虑在内核内部添加代码时,一个很好的建议是:不要!

标签: c linux sockets


【解决方案1】:
while( readlen == 128 * 4096 );

while 条件错误。你应该检查readlen &gt; 0

read 不要求只为您提供完全填满的缓冲区。在最坏的情况下(目前的 TCP 堆栈极不可能),它可以一个一个地给你字节。

无论如何,如果服务器在传递输出后没有关闭连接,你必须继续阅读,直到你得到承诺的Content-Length

【讨论】:

  • 我修改为 while(readlen == 0) 但仍以 2880 字节结束。有人说可能是 Proxy-Connection: keep-alive 的问题,需要改成 Proxy-Connection: close。没试过。有可能吗?
  • 我修改为 while(readlen == 0) 但仍以 2880 字节结束 你为什么这样做?
  • 我发现它可以工作,只是很慢,每个到服务器的连接都会空闲一段时间,然后接收一部分数据,然后关闭。然后一个新的连接开始接收其余的,依此类推。
  • 您应该做的是检索实际的Content-Length 值,然后继续读取,无论您选择使用何种缓冲区大小,直到读取指定的字节数。您在显示的代码中没有这样做。
猜你喜欢
  • 1970-01-01
  • 2013-01-31
  • 2015-04-05
  • 1970-01-01
  • 2012-12-06
  • 1970-01-01
  • 1970-01-01
  • 2019-10-26
  • 2018-08-25
相关资源
最近更新 更多