2014-04-02 33 views
2

我想了解何時使用HttpWebRequest建立TCP連接時,如何使用ServicePoint合併和重用這些連接。httpwebrequest中如何創建TCP連接,以及它如何與servicepoint相關?

我已經看了看system.dll中,並試圖通過使用ILSpy和反射器的代碼瀏覽,不知何故沒看插座的任何引用,建立TCP連接等

下面我粘貼的反編譯代碼 - 可以任何請給我提示或重定向我,這樣我就可以理解:

  1. 當TCP連接已創建?
  2. 這些連接如何保持活躍,彙集並使用ServicePoint重用?

代碼段從HttpWebRequest的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; 
    } 

回答

4

K,通過代碼瀏覽一些時間,我想以後我有點理解抽象。基本上servicepoint,servicepoint管理器,如何創建tcp連接,連接已被彙集,排隊等,總是困惑我。以下信息樣的幫助我 - 希望這是對別人誰是好奇或想了解這些細節有用:

的ServicePoint:「連接」到特定主機的高層次抽象(目標主機IP:端口) (這就是爲什麼前,函數靜態的ServicePoint FindServicePoint(字符串主機,詮釋端口)在servicePointManger定義

ServicePointManager:顧名思義它的全局(靜態),其管理服務點類

連接(內部類):基本上這是我認爲代表TCP連接的那個。它基本上來自System.Net.PoolStream(內部類 - 它具有它使用的套接字的定義),它來源於流。

ConnectionGroup(內部類):每個HttpWebRequest都與一個連接組相關聯。

(基本上根據connectionLimit它使用其的ServicePoint屬性)每HttpWebRequest的連接對象的數目創建至多connectionLimit(可全局通過ServicePointManager進行配置,並且還每HttpWebRequest的)如果達到了連接限制,其僅僅排隊並傳遞給線(很可能 - 但仍然沒有得到這樣做的代碼)。

如果您要連接到本地計算機上的服務,那麼servicepoint.connectionlimit不再等於servicepointmanager.defaultconnectionlimit。它默認爲; INT。MAXVALUE(或7FFFFFFF)(可參考:http://blogs.microsoft.co.il/idof/2011/06/20/servicepointmanagerdefaultconnectionlimit-2-depends/

更新:

貌似以下兩個鏈接也很管用:

System.Net.ServicePointManager.DefaultConnectionLimit and .MaxServicePointIdleTime

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

最好問候!

相關問題