高分求问:request.BeginGetResponse(),得到的stream都有问题,没法用。

srhouyu 2013-02-03 08:31:41
一个代理验证的程序,发现绝大多数代理返回的网页的stream都有问题。这问题就是,当我使用stream建立StreamReader的时候,它会有异常:“stream.Length”引发了“System.NotSupportedException”类型的异常。

这是一开始连接的时候

HttpWebRequest request = HttpWebRequest.Create("http://www.baidu.com") as HttpWebRequest;
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8";
request.Proxy = new WebProxy(this.ip + ":" + this.port);

// 自定义的ValidationRequestState类
// 保存了一些异步返回时候所需的原request的信息以及其他信息
ValidationRequestState state = new ValidationRequestState(request, this);

// 异步返回的请求
IAsyncResult result = request.BeginGetResponse(new AsyncCallback(OnRequestReturn), state);


这是返回的处理函数

// 返回的处理
private void OnRequestReturn(IAsyncResult result)
{
// 把之前保存的信息提取出来
ValidationRequestState state = result.AsyncState as ValidationRequestState;
HttpWebRequest request = state.request;
ProxyItem proxy = state.proxy;
HttpWebResponse response;
try
{
// 在这里,有时候会异常有时候不会。
// 如果不异常,以后就能得到一个stream
response = (HttpWebResponse)request.EndGetResponse(result);
}
catch //(Exception e)
{
if (proxy._validationFinished)
return;
proxy.lastState = "连接错误";
proxy.validationCount++;
proxy.failAfterLastSuccessCount++;
proxy.delay = -1;
this._validationFinished = true;
return;
}
// 验证结果
// 这里得到的这个stream,它的Length属性绝大多数时间都会引发
// System.NotSupportedException类型的异常
Stream stream = response.GetResponseStream();
// 所以这个html也没法得到了。以后的代码就没用了
string html = Common.StreamToString(stream, response.CharacterSet);
// ......
}


不知道我的操作方式是否有问题?以及返回的stream为什么会出现这么多问题呢?
...全文
307 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
qldsrx 2013-02-04
  • 打赏
  • 举报
回复
再看看你用的代理服务器中,是否使用到ssl连接,如果代理服务器会发布一个证书给你,而你却不接受那个证书,也会有请求被中止的错误,有关证书的处理,参考如下代码:
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(allowCert);

        private static bool allowCert(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
        {
            return true;
        }
qldsrx 2013-02-04
  • 打赏
  • 举报
回复
出现了异常“请求被中止: 请求已被取消。” 这个是WEB请求的一般性错误,是由于代理服务器主动中断了连接,也许是代理配置问题,亦或者是访问了禁止访问的网站。
srhouyu 2013-02-04
  • 打赏
  • 举报
回复
还是需要顶一下
srhouyu 2013-02-03
  • 打赏
  • 举报
回复
引用 2 楼 qldsrx 的回复:
如果你一定要用流的Length属性或Position属性来随机定位,那么你可以构造一个MemoryStream来,再定义一个缓存变量byte[1024],然后用网络流的Read方法循环读取,每次1024个字节到缓存(返回值为实际读取字节数),并将缓存中的实际读取字节数通过Write方法写入MemoryStream中,循环直到Read方法返回0个字节为止,然后你操作那个Me……
我试了一下复制到MemoryStream中的方法。但是我调用stream.Read()时候,出现了异常“请求被中止: 请求已被取消。”这不知道是怎么回事?
srhouyu 2013-02-03
  • 打赏
  • 举报
回复
引用 5 楼 hjywyj 的回复:
StreamReader reader = new StreamReader(stream); string str = reader.ReadToEnd();
我现在就是这样的方法。new StreamReader(stream)这里就异常了,说不支持Length属性。
  • 打赏
  • 举报
回复
StreamReader reader = new StreamReader(stream); string str = reader.ReadToEnd();
srhouyu 2013-02-03
  • 打赏
  • 举报
回复
引用 2 楼 qldsrx 的回复:
如果你一定要用流的Length属性或Position属性来随机定位,那么你可以构造一个MemoryStream来,再定义一个缓存变量byte[1024],然后用网络流的Read方法循环读取,每次1024个字节到缓存(返回值为实际读取字节数),并将缓存中的实际读取字节数通过Write方法写入MemoryStream中,循环直到Read方法返回0个字节为止,然后你操作那个Me……
我不太清楚这里的stream是已经完全载入到本地完毕了,还是需要等待呢。如果已经完全载入到本地了,那么我是不是直接循环Read到一个MemoryStream,不用等待就可以?
srhouyu 2013-02-03
  • 打赏
  • 举报
回复
引用 1 楼 qldsrx 的回复:
你要记住,网络有个的流,只支持顺序读写操作,不支持获取流的长度和定位流的位置,它只是将发送和接收的过程模拟成流对象而已,并不能具有所有流的功能。所以我们一般都直接使用Socket对象的Send和Receive方法来处理,更直观,而流的使用往往是作为函数的输入输出参数,那个场合通用性较好,但是作为一个基本的流(Stream),只有Read和Write方法是肯定支持的,其他方……
多谢。你说的意思是不是,这个stream在返回的那一瞬间,还可能没有完全载入完毕?那么,如果暂时沿用我的方法而不用Socket对象,我要把它转为string的时候,该用什么样的方法比较合适呢?我之前是直接ReadToEnd()好像需要流的Length属性,所以不行。
qldsrx 2013-02-03
  • 打赏
  • 举报
回复
如果你一定要用流的Length属性或Position属性来随机定位,那么你可以构造一个MemoryStream来,再定义一个缓存变量byte[1024],然后用网络流的Read方法循环读取,每次1024个字节到缓存(返回值为实际读取字节数),并将缓存中的实际读取字节数通过Write方法写入MemoryStream中,循环直到Read方法返回0个字节为止,然后你操作那个MemoryStream就可以很随意了。
qldsrx 2013-02-03
  • 打赏
  • 举报
回复
你要记住,网络有个的流,只支持顺序读写操作,不支持获取流的长度和定位流的位置,它只是将发送和接收的过程模拟成流对象而已,并不能具有所有流的功能。所以我们一般都直接使用Socket对象的Send和Receive方法来处理,更直观,而流的使用往往是作为函数的输入输出参数,那个场合通用性较好,但是作为一个基本的流(Stream),只有Read和Write方法是肯定支持的,其他方法属性不见得支持,也完全不需要支持。

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧