在 httpwebrequest 中创建 TCP 连接的方式和位置,以及它与 servicepoint 的关系

本文关键字:关系 servicepoint 位置 httpwebrequest 创建 TCP 方式 连接 | 更新日期: 2023-09-27 17:56:17

我试图找出在使用HttpWebRequest时何时建立TCP连接,这些连接是如何使用ServicePoint池化和重用的。

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

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

  1. 何时创建 TCP 连接?
  2. 如何使用 ServicePoint 保持这些连接处于活动状态、池化和重用?

来自 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;
    }

在 httpwebrequest 中创建 TCP 连接的方式和位置,以及它与 servicepoint 的关系

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

ServicePoint:与特定主机(目标主机 Ip:port)的"连接"的高级抽象(这就是为什么例如,函数静态 ServicePoint FindServicePoint(string host, int port) 是在 servicePointManger 中定义的。

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

连接(内部类):基本上这是我认为代表TCP连接的那个。 它基本上派生自System.Net.PoolStream(内部类 - 它有它使用的套接字的定义),它派生自Stream。

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

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

如果要连接到本地计算机上的服务,则 servicepoint.connectionlimit 不再等于 servicepointmanager.defaultconnectionlimit。 它默认为; int。最大值 (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

此致敬意!