在 httpwebrequest 中如何以及在何处创建 TCP 连接,它与 servicepoint 有什么关系? [英] How and where the TCP connection has been created in httpwebrequest, and how is it related to servicepoint?

查看:43
本文介绍了在 httpwebrequest 中如何以及在何处创建 TCP 连接,它与 servicepoint 有什么关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找出在使用 HttpWebRequest 时建立 TCP 连接的时间,以及如何使用 ServicePoint 汇集和重用这些连接.

我查看了 system.dll,并尝试使用 ILSpy 和 Reflector 浏览代码,不知何故没有看到任何对套接字、建立 tcp 连接等的引用.

下面我粘贴了反编译的代码 - 任何人都可以给我提示或重定向我以便我理解:

  1. TCP 连接何时创建?
  2. 如何使用 ServicePoint 保持这些连接的活动、汇集和重用?

来自 System.dll 的 HttpWebRequest 的代码片段:

公共覆盖流 GetRequestStream(){传输上下文上下文;返回 this.GetRequestStream(out context);}公共流 GetRequestStream(出 TransportContext 上下文){如果(登录.打开){Logging.Enter(Logging.Web, this, "GetRequestStream", "");}上下文 = 空;this.CheckProtocol(true);if ((this._WriteAResult == null) || !this._WriteAResult.InternalPeekCompleted){锁(这个){如果 (this._WriteAResult != null){throw new InvalidOperationException(SR.GetString("net_repcall"));}如果 (this.SetRequestSubmitted()){throw new InvalidOperationException(SR.GetString("net_reqsubmitted"));}如果 (this._ReadAResult != null){throw ((异常) this._ReadAResult.Result);}this._WriteAResult = new LazyAsyncResult(this, null, null);this.Async = false;}this.CurrentMethod = this._OriginVerb;while (this.m_Retry && !this._WriteAResult.InternalPeekCompleted){this._OldSubmitWriteStream = null;this._SubmitWriteStream = null;this.BeginSubmitRequest();}while (this.Aborted && !this._WriteAResult.InternalPeekCompleted){if (!(this._CoreResponse is Exception)){Thread.SpinWait(1);}别的{this.CheckWriteSideResponseProcessing();}}}ConnectStream connectStream = this._WriteAResult.InternalWaitForCompletion() as ConnectStream;this._WriteAResult.EndCalled = true;如果(连接流 == 空){如果(登录.打开){Logging.Exception(Logging.Web, this, "EndGetRequestStream", this._WriteAResult.Result as Exception);}throw ((异常) this._WriteAResult.Result);}context = new ConnectStreamContext(connectStream);如果(登录.打开){Logging.Exit(Logging.Web, this, "GetRequestStream", connectStream);}返回连接流;}

解决方案

K,在浏览代码一段时间后,我觉得我有点理解这些抽象了.基本上是服务点、服务点管理器、如何创建 tcp 连接、连接已池化、排队等.总是让我感到困惑.以下信息对我有所帮助 - 希望这对其他好奇或试图了解这些细节的人有用:

ServicePoint:连接"到特定主机(目标主机 Ip:port)的高级抽象(这就是为什么例如,函数静态 ServicePoint FindServicePoint(字符串主机,int 端口)在 servicePointManger 中定义.

ServicePointManager:顾名思义,它是管理服务点的全局(静态)类.

Connection(内部类):基本上这是我认为代表 TCP 连接的一种.它基本上派生自 System.Net.PoolStream (内部类 - 它具有其使用的套接字的定义),它派生自流.

ConnectionGroup(内部类):每个 HttpWebRequest 都与一个连接组相关联.(基本上基于 connectionLimit,它最多创建 connectionLimit(可以通过 ServicePointManager 全局配置,也可以使用其 servicePoint 属性为每个 httpwebrequest 配置)每个 httpwebrequest 的连接对象数)

如果达到连接限制,它只是排队并传递给线路(很可能 - 但仍然没有获得执行此操作的代码).

如果你连接到本地机器上的服务,servicepoint.connectionlimit 不再等于 servicepointmanager.defaultconnectionlimit.它默认为;int.Maxvalue(21474836477FFFFFFF)(您可以参考:http://blogs.microsoft.co.il/idof/2011/06/20/servicepointmanagerdefaultconnectionlimit-2-depends/)>

更新:

看起来以下两个链接也很有用:

System.Net.ServicePointManager.DefaultConnectionLimit 和 .MaxServicePointIdleTime

http:///blogs.msdn.com/b/jpsanders/archive/2009/05/20/understanding-maxservicepointidletime-and-defaultconnectionlimit.aspx

最好的问候!

I am trying to find out when the TCP connection has been established while using HttpWebRequest, how these connections have been pooled and reused using ServicePoint.

I have looked at the system.dll, and tried to browse through the code using ILSpy and Reflector, somehow didn't see any references to sockets, establishing tcp connection etc.

Below I have pasted the decompiled code - can any please give me tips or redirect me so that I can understand:

  1. When the TCP connection has been created?
  2. How these connections are kept alive, pooled and reused using ServicePoint?

Code snippet from HttpWebRequest of System.dll:

public override Stream GetRequestStream()
    {
        TransportContext context;
        return this.GetRequestStream(out context);
    }

    public Stream GetRequestStream(out TransportContext context)
    {
        if (Logging.On)
        {
            Logging.Enter(Logging.Web, this, "GetRequestStream", "");
        }
        context = null;
        this.CheckProtocol(true);
        if ((this._WriteAResult == null) || !this._WriteAResult.InternalPeekCompleted)
        {
            lock (this)
            {
                if (this._WriteAResult != null)
                {
                    throw new InvalidOperationException(SR.GetString("net_repcall"));
                }
                if (this.SetRequestSubmitted())
                {
                    throw new InvalidOperationException(SR.GetString("net_reqsubmitted"));
                }
                if (this._ReadAResult != null)
                {
                    throw ((Exception) this._ReadAResult.Result);
                }
                this._WriteAResult = new LazyAsyncResult(this, null, null);
                this.Async = false;
            }
            this.CurrentMethod = this._OriginVerb;
            while (this.m_Retry && !this._WriteAResult.InternalPeekCompleted)
            {
                this._OldSubmitWriteStream = null;
                this._SubmitWriteStream = null;
                this.BeginSubmitRequest();
            }
            while (this.Aborted && !this._WriteAResult.InternalPeekCompleted)
            {
                if (!(this._CoreResponse is Exception))
                {
                    Thread.SpinWait(1);
                }
                else
                {
                    this.CheckWriteSideResponseProcessing();
                }
            }
        }
        ConnectStream connectStream = this._WriteAResult.InternalWaitForCompletion() as ConnectStream;
        this._WriteAResult.EndCalled = true;
        if (connectStream == null)
        {
            if (Logging.On)
            {
                Logging.Exception(Logging.Web, this, "EndGetRequestStream", this._WriteAResult.Result as Exception);
            }
            throw ((Exception) this._WriteAResult.Result);
        }
        context = new ConnectStreamContext(connectStream);
        if (Logging.On)
        {
            Logging.Exit(Logging.Web, this, "GetRequestStream", connectStream);
        }
        return connectStream;
    }

解决方案

K, after browsing through code some time I think I kind of understood the abstractions. Basically servicepoint, servicepoint manager, how the tcp connection has been created, connections have been pooled, queued etc. always confused me. Below information kind of helped me - hopefully this is useful for others who are curious or tried to understand these details:

ServicePoint: High level abstraction of 'connection' to a particular host (destination Host Ip:port) (that's why for ex, function static ServicePoint FindServicePoint(string host, int port) is defined in servicePointManger.

ServicePointManager: as the name indicates its the global (static) class which manages service points.

Connection (internal class): Basically this is the one I think that represents TCP connection. it basically derives from System.Net.PoolStream (internal class - it has the definitions of the sockets its using) which derives from stream.

ConnectionGroup (internal class): Each HttpWebRequest is associated with a connection group. (basically based on connectionLimit it creates at most connectionLimit (can be configured globally through ServicePointManager, and also per httpwebrequest using its servicePoint property) number of connection objects per httpwebrequest)

If the connection limit is reached, its simply queued and passed to the wire (most likely - but still didn't get the code which does this).

And if you are connecting to service on the local machine, the servicepoint.connectionlimit no longer equal to servicepointmanager.defaultconnectionlimit. it defaults to; int.Maxvalue (2147483647 or 7FFFFFFF) ( you may refer to: http://blogs.microsoft.co.il/idof/2011/06/20/servicepointmanagerdefaultconnectionlimit-2-depends/ )

Update:

Looks like following two links are useful too:

System.Net.ServicePointManager.DefaultConnectionLimit and .MaxServicePointIdleTime

http://blogs.msdn.com/b/jpsanders/archive/2009/05/20/understanding-maxservicepointidletime-and-defaultconnectionlimit.aspx

Best Regards!

这篇关于在 httpwebrequest 中如何以及在何处创建 TCP 连接,它与 servicepoint 有什么关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆