使用HttpWebResponse读取"分块"响应
时间:2020-03-05 18:40:54 来源:igfitidea点击:
使用StreamReader读取HttpWebResponse的GetResponseStream()返回的流时,我无法读取"分块"响应:
// response is an HttpWebResponse StreamReader reader = new StreamReader(response.GetResponseStream()); string output = reader.ReadToEnd(); // throws exception...
当调用reader.ReadToEnd()
方法时,我得到以下System.IO.IOException:无法从传输连接中读取数据:连接已关闭。
当服务器返回"非分块"响应时,以上代码可以正常工作。
我能够使其正常工作的唯一方法是对初始请求使用HTTP / 1.0(而不是默认的HTTP / 1.1),但这似乎是一个me脚的解决方法。
有任何想法吗?
@查克
解决方案效果很好。它仍然在最后一个Read()上抛出相同的IOExeception。但是在检查了StringBuilder的内容之后,看起来好像已经收到了所有数据。因此,也许我只需要在尝试捕获中包装Read()并吞下"错误"。
解决方案
回答
还没有尝试过"块状"响应,但是类似的东西会起作用吗?
StringBuilder sb = new StringBuilder(); Byte[] buf = new byte[8192]; Stream resStream = response.GetResponseStream(); string tmpString = null; int count = 0; do { count = resStream.Read(buf, 0, buf.Length); if(count != 0) { tmpString = Encoding.ASCII.GetString(buf, 0, count); sb.Append(tmpString); } }while (count > 0);
回答
克雷格(Craig),虽然看不到我们正在阅读的流,但是调试起来有些困难,但是也许我们可以将count变量的设置更改为:
count = resStream.Read(buf, 0, buf.Length-1);
这有点骇人听闻,但是如果最后一次读取使我们丧命并且不返回任何数据,那么从理论上讲,这将避免该问题。我仍然想知道为什么流正在这样做。
回答
我遇到了同样的问题(这就是我到这里结束的方式:-)。最终将其追溯到分块流无效的事实,即最终的零长度块丢失了。我想出了以下代码,可同时处理有效和无效的分块流。
using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { StringBuilder sb = new StringBuilder(); try { while (!sr.EndOfStream) { sb.Append((char)sr.Read()); } } catch (System.IO.IOException) { } string content = sb.ToString(); }