Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么从服务器读取实际字节';s响应小于内容长度?_C_Linux_Sockets - Fatal编程技术网

C 为什么从服务器读取实际字节';s响应小于内容长度?

C 为什么从服务器读取实际字节';s响应小于内容长度?,c,linux,sockets,C,Linux,Sockets,我正在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,appl

我正在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=
HTTP/1.1200正常
内容长度:3170
内容类型:text/html
内容位置:http://www.yongchuan.org/index.html
最后修改:2011年7月22日星期五01:28:50 GMT
接受范围:字节
ETag:“72d9d7b5e48cc1:1a73”
服务器:Microsoft IIS/6.0
X-Powered-By:ASP.NET
日期:2012年3月4日星期日格林尼治标准时间16:26:05
..............
��ѧ�ڿγ̣�
问题是,代理读取的实际字节大小是2880,数据突然结束,远小于上下文长度: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 );
241 int readlen;
242字符缓冲区[128*4096];
243 do{
244 readlen=read(servfd,缓冲器,128*4096);
245 printf(“readlen:%d\n”,readlen);
246如果(读数<0){
247 perror(“从服务器读取()失败”);
248     }   
249 printf(“读取内容:\n%s”,缓冲区2);
250写入(cliefd、buffer、readlen);
251}而(readlen==128*4096);
这里servfd是服务器的套接字,cliefd是客户端的套接字。 可能的原因是什么?谢谢

while条件是错误的。您应该改为选中
readlen>0

没有要求
读取
只会将缓冲区完全填满。在最坏的情况下(对于当前的TCP堆栈来说,这是不可能的),它可能会一个接一个地将字节传递给您


无论如何,如果服务器在交付输出后未关闭连接,则必须继续读取,直到获得承诺的
内容长度。

我修改为while(readlen==0),但仍以2880字节结束。一些ppl说这可能是代理连接的问题:保持活动状态,需要更改为代理连接:关闭。我没试过。可能吗?我修改为while(readlen==0),但仍然以2880字节结束。为什么这样做?我发现它可以工作,只是速度非常慢,与服务器的每个连接都会闲置一段时间,然后接收部分数据,然后关闭。然后,一个新连接开始接收其余的连接,依此类推。您应该做的是检索实际的
内容长度
值,然后继续读取,无论您选择使用的缓冲区大小如何,直到读取指定的字节数为止。在你展示的代码中没有这样做,我认为你不是在内核3.0中编写代理,而是在内核3.0中编写代理;您的代理是一个在内核之外运行的用户级应用程序(并不时向内核发出系统调用)。。在Linux内核中编写一个代理(例如作为一个怪物模块)是疯狂的;当考虑在内核中添加代码时,一个很好的建议是:不要!
while( readlen == 128 * 4096 );