【问题标题】:how to handle a chunked response from a server?如何处理来自服务器的分块响应?
【发布时间】:2012-03-15 20:38:41
【问题描述】:

我正面临用 C 语言编写基本代理服务器的最后一个主要障碍。

我的服务器已成功接收来自浏览器的请求,然后成功地将它们发送到主机,无论它们在哪里。我也成功收到了楼主的回复!除了,这是我尝试通过服务器连接到 Google 时得到的结果:

Rcvd message from server: 

----

HTTP/1.1 200 OK
Date: Thu, 15 Mar 2012 20:35:11 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=83a7c2e6675a9a9f:FF=0:TM=1331843711:LM=1331843711:S=7I7RIVV1B-HxhWJR; expires=Sat, 15-Mar-2014 20:35:11 GMT; path=/; domain=.google.com
Set-Cookie: NID=57=KvqnXtYNkJZBryXL5zzhG5eH8Or2_PDWDqT_kU35PvOro_mAFiLiTSjPHOnWWxxm3R0vKYnzEeVkAPFKK366lZiNZGpjhO2-II5OeZQnWe09H-jZdePsrN-SnBdQ2ENT; expires=Fri, 14-Sep-2012 20:35:11 GMT; path=/; domain=.google.com; HttpOnly
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Transfer-Encoding: chunked

1000
<!doctype html><html itemscope itemtype="http://schema.org/WebPage"><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta name="description" content="Search the world&#39;s information, including webpages, images, videos and more. Goo

你看到它是如何切断的吗?因为“传输编码:分块”。现在我如何让服务器继续向我发送其余的块?因为在第一个之后,它就停止了。我是否需要将 read() 放在一个 while 循环中,并说只要有要阅读的内容就继续阅读并转发给客户端吗?

编辑:

好的,这是我现在的代码。这会首先读取服务器的响应(在名为“sock”的套接字上),将其写入客户端(“newsock”),然后进入一个 while 循环以继续读取更多服务器响应并将它们发送到客户端。我还没有测试过这种形式的代码。除了一些错误检查漏洞之外,您是否发现任何明显的问题?

/*WRITING SERVER RESPONSE TO CLIENT*/

  char buffer2[1024];

  n = read(sock, buffer2, 1024 );

  if ( n < 1 )
  {
    perror( "read() failed" );
    return EXIT_FAILURE;
  }

  else
  {
    buffer2[n] = '\0';
    printf( "Rcvd message from server: \n\n----\n\n%s\n\n----\n\n", buffer2 );
  }

  n = write( newsock, buffer2, strlen( buffer2 ) );

  while((n = read(sock, buffer2, 1024 )) >= 1)
  {
      buffer2[n] = '\0';
      printf( "Rcvd message from server: \n\n----\n\n%s\n\n----\n\n", buffer2 );
      n = write( newsock, buffer2, strlen( buffer2 ) );
  }

【问题讨论】:

  • 你能详细说明你是做什么的(放置你的相关C代码),为什么说它cut?
  • 我可以附上一些代码,除了我一直在编辑它试图自己解决它,我还没有测试它,所以现在我没有知道它会做什么。需要一些时间。而且我认为如果您向右滚动,您会看到截止点——显然 Google.com 的代码不止于此。它只是停在元标记的中间。还有更多。
  • @Aerovistae,你如何使用内容长度来响应?
  • 对不起,您能详细说明一下这个问题吗?我知道你要去哪里,但我不确定如何使用内容长度。真的像只读取内容长度标题所说的那样简单,然后停止吗?
  • 关于图像(和一般的二进制数据),不要 NUL 终止 buffer2 并使用 strlen - 这仅适用于文本数据。在所有情况下,只需使用n 作为要发送的数据长度。 (当n 为1024 时,NUL 终止buffer2 也超出了数组的末尾。)

标签: c http network-programming chunked-encoding


【解决方案1】:

您不能使用 strlen 来获取缓冲区的大小, strlen 仅用于获取字符串的大小,您可能正在读取一些二进制数据,因为不仅有文本通过您的代理(图像。 ..)。尝试使用 read 返回的值,即实际读取的字节数。

用 '\n' 结束你的字符串变得毫无用处。

【讨论】:

  • 但是块是文本和图像的混合,不是吗?我应该永远不终止,还是会导致文本部分出错?
  • 您没有理由以空值终止问题是您的推理好像是 c 刺痛,而不是原始数据。因此,在您的数据中间,您可能会得到一个等于 0 的字节。这就是您的 strlen 不起作用的原因。不要将其视为文本和图像,而应将其视为数据。所以没有理由空终止
  • 可以将原始数据保存在 char 数组中吗?我不知道该放入什么其他类型的变量。
  • 是的,完全没问题。不要将 char 视为一个字符,而是将其视为 1byte 的数据容器。如果您还没有这样做,请尝试在文本编辑器中打开一个二进制文件,您会发现即使它对人类来说完全不可读,但它工作正常。
猜你喜欢
  • 1970-01-01
  • 2016-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多