关于.NET(C#)里使用HttpWebRequest中碰到的一些和Keep-Alive相关的内容

发布时间 2023-09-08 14:27:02作者: Easy C#

c#采集其他网站数据时,会比较多的使用HttpWebRequest来实现HTTP访问,读取网站内容。

最近关注一下几个问题:

  1. HttpWebRequest.ServicePoint
  2. ServicePointManager
  3. request.KeepAlive
  4. ServicePoint.SetTcpKeepAlive
  5. ServicePoint.ConnectionLimit
  6. ServicePoint.MaxIdleTime
  7. ServicePointManager.MaxServicePointIdleTime
  8. ServicePoint.ConnectionLeaseTimeout

一、ServicePoint:

  每个请求背后都有一个ServicePoint,可以把ServicePoint想象成请求背后的TCP连接对象,通过设置ServicePoint的相关属性,可以控制TCP连接的一些行为。

 

二、ServicePointManager

  顾名思义,这个是对 ServicePoint 进行管理的类,设置ServicePointManager的一些属性,就可以控制ServicePoint默认的一些属性,比如下面出现的Tcp KeepAlive,Connection Limit等等。

 

三、request.KeepAlive

  request.KeepAlive这个bool类型KeepAlive,是对Http请求的KeepAlive的控制,不是对TCP的KeepAlive。可以参考:

    HTTP Keep-Alive详解[转]  

    HTTP协议Keep-Alive模式详解和HTTP头字段总结 

 四、ServicePoint.SetTcpKeepAlive

  ServicePoint的SetTcpKeepAlive是设置TCP连接的KeepAlive特性,三个参数SetTcpKeepAlive(bool enabled, int keepAliveTime, int keepAliveInterval)的意思分别是:是否启用TCP的KeepAlive。关于TCP的Keep-Alive可以参考这个文章:UNIX网络编程——socket的keep-alive 

 

五、ConnectionLimit

  ServicePoint.ConnectionLimit和ServicePointManager.DefaultConnectionLimit都可以设置对某个URI资源可以同时访问的最大数量。HTTP协议规范里说,一个用户最多可以同时建立两个HTTP连接,如果大量线程同时请求一个站点,可能会受到限制。ConnectionLimit在Windows 10、Windows Server 2008 R2、Windows7 里默认限制是2。修过修改ConnectionLimit应该可以允许更多的请求同时进行。

 

六、MaxIdleTime

  

 

附1:

.NET的 HttpWebRequest 设置KeepAlive时,有一个问题,就是只有第一次发送出去的请求是带有KeepAlive标头的,后续的请求没有KeepAlive标头,解决这个问题的方式,是使用反射。

例如:

1 //.Net Framework 存在设置 HTTP Keep-Alive的BUG,每域名只有第一次请求Keep-Alive标头存在,后续请求需要靠此代码修正
2             var sp = request.ServicePoint;
3             var prop = sp.GetType().GetProperty("HttpBehaviour", BindingFlags.Instance | BindingFlags.NonPublic);
4             prop.SetValue(sp, (byte)0, null);

这样设置之后,每次请求都可以发送KeepAlive标头。