2013-08-22 28 views
2

我遇到了問題System.Net.Sockets.TcpClient爲什麼TcpClient與構造函數中的參數連接速度較慢?

一個簡單的測試應用程序只是打開一個連接,發送一些數據,並關閉。另一端有一臺簡單的服務器,其性能非常好。

的代碼看起來是這樣的:

var client = new TcpClient("localhost", 1234); 
using (var stream = client.GetStream()) 
using (var writer = new StreamWriter(stream)) 
{ 
    writer.Write("foo"); 
    writer.flush(); 
} 
client.Close(); 

它工作得很好,但我注意到,單元測試正在採取> 1000ms的運行。當我把它放在一個稱爲10次的循環中時,它大於10,000毫秒。

後與客戶端和服務器上的時序調試的時間,我發現它是緩慢的。
此修復程序是代碼從:

var client = new TcpClient("localhost", 1234); 

這樣:

var client = new TcpClient(); 
client.Connect("localhost", 1234); 

這使所有的差異。一次傳球大約需要10ms,而10次傳球則少於100ms。

WHY ???

+2

在這篇文章中的最後一句話是我對.NET的大部分感覺 –

+0

我測試了它,沒有看到任何區別。你可以發佈一個簡單的自包含代碼(客戶端+服務器)來顯示問題嗎? – I4V

回答

3

http://msdn.microsoft.com/en-us/library/115ytk56(v=vs.110).aspx

「如果啓用了IPv6和TcpClient的(字符串,Int32)方法被調用來連接到解析爲IPv6和IPv4地址的主機,對IPv6地址的連接將嘗試首先在IPv4地址之前,如果主機沒有監聽IPv6地址,這可能會延遲建立連接的時間。「

我不知道爲什麼默認的構造函數也不這樣做(我本來希望你必須使用構造函數,它需要一個AddressFamily並在連接之前指定IPv4),但顯然它不會。

-1

你一定會喜歡這個答案。我不知道,因爲對我來說沒有意義。

使用反射器,在第2節組件的默認構造函數是

public TcpClient() : this(AddressFamily.InterNetwork) 
{ 
    if (Logging.On) 
    { 
     Logging.Enter(Logging.Sockets, this, "TcpClient", (string) null); 
    } 
    if (Logging.On) 
    { 
     Logging.Exit(Logging.Sockets, this, "TcpClient", (string) null); 
    } 
} 

上面的代碼是非常接近無操作,如果你沒有啓用日誌記錄

第二屆構造函數做(字符串主機名,int端口)完成所有這些工作,當然還有更多,但更多的一部分是對第二個示例中使用的同一個TcpClient.Connect()方法的調用。即在兩種情況下執行的代碼都非常接近。我深入研究,因爲我想知道MS代碼是如何產生這樣一個奇怪的問題 - 我可以通過查看這些散佈問題來得到最好的結果,他們沒有奇怪的問題。我以爲我可能會看到一些奇怪的DNS查找問題,或類似但沒有骰子。

連接套接字幾乎可以保證減慢速度,但我認爲這最多需要大約100或200毫秒,除非您的Internet連接或DNS服務器或代理服務器非常差。但是我沒有看到任何事情會導致你的2例有明顯不同的行爲,有1例外。您的示例並未完整顯示您的使用條款可能會有所不同。如果套接字上有觸發緩慢行爲的清除代碼,則可能在您的兩個示例中有所不同。

+0

不同之處在於添加了更多的技術細節,您通常會用它來調試問題,您分享的內容也沒什麼不同。 –

+1

不是一個答案,只是一個非常長的**評論** – I4V

+0

是的,它只是一個長期的意見,但你不能對這麼長的評論 - 你有更好的方法嗎? –

相關問題