Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
467 views
in Technique[技术] by (71.8m points)

c# - How and where the TCP connection has been created in httpwebrequest, and how is it related to servicepoint?

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;
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...