2009-11-17 136 views
2

我有一個程序,從數據庫中拉出一個IP地址列表,總共約3000個。每個地址都與遠程機器相關,遠程機器應運行我的應用程序作爲客戶端的.NET Remoting服務器。我需要連接到每個通過.Net Remoting撤回一些數據。但是,如果遠程站點存在某種問題,則需要等待很長時間,直到程序返回。檢查多臺機器上的開放端口

我已經研究並發現,在使用Sockets嘗試.Net Remoting連接之前,我可以檢查.Net Remoting端口。此外,使用異步Socket.BeginConnect方法,我可以超時在指定的超時期限內不返回的任何連接。如果我一次檢查一個IP地址,但對於X個地址,這可能會很好,這可能會花費(X * timeout)時間來完成。所以我的下一步是引入一個線程池,以便我可以同時檢查多個站點:

我爲循環中的每個ip創建一個OpenPortChecker對象,爲它提供一個ManualResetEvent和ip,然後將它排入線程池。一旦所有內容都被添加到池中,我將等待所有線程完成,方法是遍歷ManualResetEvents列表並在每個線程上調用WaitOne()。 OpenPortChecker包含一個方法,對上面詳細描述的指定ip執行一次定時的Socket.BeginConnect調用,然後調用ManualResetEvent.Set()在完成時發出信號。

然而,這並不像我預料的那樣工作:如果我不限制線程池的大小,所有的連接都會由於超時而失敗(儘管我知道它們是可用的),並且最終程序因爲線程太多而失敗創建。事實上,我可以看到任務管理器中的線程數量一路上升,儘管每個線程只能在指定的超時時間內返回到池中。這可以通過限制線程池大小來解決,但時間問題又回來了。此外,除非我severley限制池(大約10個線程)並將超時設置爲20秒,否則連接都不會成功。然後,這成爲線程數量和超時期限之間的平衡行爲,這看起來是錯誤的,並且可能會隨着運行的機器而波動。事實上,如果它比一次查看一個地址更好,這是有爭議的。

我是否限制了一次可以連接的連接數?我在某處做錯了什麼?有更好的方法嗎?任何幫助,將不勝感激。

感謝,

詹姆斯

+1

您使用的是什麼操作系統?是的,您可以進行有限數量的連接 - 尤其是在非服務器操作系統中。 – 2009-11-17 10:34:17

+0

嗨。我正在運行Windows XP Professional。所以我需要限制線程的數量以匹配允許的連接數量?這種方法的問題在於,用戶可能正在運行其他應用程序,這些應用程序已經在使用這些配額中的一部分。 – James 2009-11-17 10:38:01

+0

你可以分享OpenPortChecker的代碼嗎? – 2009-11-18 22:29:45

回答

0

據我所知,該錯誤是不同的,當遠程站點不回答,當遠程站點拒絕連接,並且在連接不能由於某種成立的傳出連接配額。請記住,簡單的網絡接口擁塞可能是罪魁禍首,而不是任何類型的配額。

0

在C#中可用的非阻塞I/O?然後使用一個線程,您可以啓動多個連接嘗試,並在成功或超時時獲得回叫。

1

似乎你有tcpip.sys「半開連接」限制。 如果你有這些操作系統之一,你有侷限性:

  • Windows XP服務包2/3
  • 的Windows 2003 Service Pack 1和上述
  • 的Windows Vista/2008不帶Service Pack或Service Pack 1.
  • Windows 7早於RTM。

要繞過這個限制:

  • 在Windows XP/2003 - 安裝第三方補丁 - http://www.lvllord.de
  • 在Windows Vista/2008 - 安裝Service Pack 2
  • 在Windows 7 - 安裝RTM版本。
0

感謝您的回覆。我現在已經解決了這個問題,所以我認爲如果別人面臨類似的問題,我會發布分享我的答案。正如Kieran Benton指出的那樣,XP允許的連接數量有10個(cmd:net config server),所以我限制了我的程序一次只能運行10個線程(儘管這仍然存在一個問題,用戶可能已經在使用一些連接配額)。接着,由羅伯特·Obryk提供的信息工作,我做了一些更多的研究Remoting的連接和發現,使通過遠程連接時,你確實可以設置超時:

IDictionary prop = ChannelServices.GetChannelSinkProperties(remObject); 
prop["timeout"] = remotingTimeout; 

在這一點上,我放棄了最初的因爲看起來這已經不再需要了,但是測試表明,如果遠程計算機可以通過指定的端口到達,遠程處理超時纔有效。如果端口關閉,則超時被忽略,並且連接掛起。因此,我的最終實現涉及定時Socket連接,首先檢查端口是否處於打開狀態,然後嘗試對響應站點進行定時Remoting調用。有點囉嗦,但它的作品!

再次感謝,

詹姆斯