2008-10-12 27 views
11

我想要在下面的條件下通過以下JUnit測試的最快和最準確的函數boolean isReachable(String host, int port)。超時值由JUnit測試本身指定,並可能被視爲「無法訪問」。什麼是在Java中檢測無法訪問的主機的最快方法?

請注意:所有答案必須是平臺無關的。這意味着,InetAddress.isReachable(int timeout)是行不通的,因爲它依賴於端口7做Windows上的平(ICMP的ping是Windows上的無證功能),而這個端口被阻止在此設置。

LAN設置:

  • thisMachine192.168.0.100
  • otherMachine192.168.0.200
  • 沒有機器叫做noMachine或具有
  • 兩臺機器正在運行的IP 192.168.0.222(總是無法訪問)端口8080上的Apache Tomcat;所有其它端口都無法訪問(包括端口7
  • example.com208.77.188.166)正在運行在端口80一個網絡服務器和當LAN連接到因特網

有時候是僅可到達的,LAN從斷開互聯網在這種情況下只有通過IP地址呼叫的本地機器可達(所有其他機器無法訪問;沒有DNS)。

所有測試均在thisMachine運行。當局域網斷開從網上

@Test(timeout=1600) // ~320ms per call (should be possible to do better) 
public void testLocalhost() { 
    // We can always reach ourselves. 
    assertTrue(isReachable("localhost", 8080)); 
    assertTrue(isReachable("127.0.0.1", 8080)); 
    assertTrue(isReachable("thisMachine", 8080)); // Even if there's no DNS! 
    assertTrue(isReachable("192.168.0.100", 8080)); 

    assertFalse(isReachable("localhost", 80)); // Nothing on that port. 
} 

@Test(timeout=5500) // ~1867ms per call (should be able to do better) 
public void testLAN() { 
    assertTrue(isReachable("192.168.0.200", 8080)); // Always connected to the LAN. 
    assertFalse(isReachable("192.168.0.222", 8080)); // No such a machine. 
    assertFalse(isReachable("noMachine", 8080)); // No such machine. 
} 

以下測試僅運行。

@Test(timeout=5600) // ~1867ms per call (reasonable?) 
public void testNoDNS() { 
    assertFalse(isReachable("otherMachine", 8080)); // No DNS. 
    assertFalse(isReachable("example.com", 80)); // No DNS & no Internet. 
    assertFalse(isReachable("208.77.188.166", 80)); // No Internet. 
} 

當LAN是連接到因特網以下測試僅運行。

@Test(timeout=5600) // ~1867ms per call (reasonable?) 
public void testHaveDNS() { 
    assertTrue(isReachable("otherMachine", 8080)); // DNS resolves local names. 
    assertTrue(isReachable("example.com", 80)); // DNS available. 
    assertTrue(isReachable("208.77.188.166", 80)); // Internet available. 
} 

回答

0

我最近的解決方案取決於使用TimedSocketsource code)與3000ms在執行連接超時。

時序:

  • 1406ms:testLocalHost()
  • 5280ms:testLAN()

甚至不能得到這些正常工作:

  • testNoDNS()
  • testHaveDNS()
0

不知道這是多麼實際。

如何做相當於traceroute(windows上的tracert),一旦你獲得成功,你可以繼續。

在企業網絡中,我見過ICMP(ping)被管理員阻止,但通常情況下,tracert仍然有效。如果你能想出一個快速的方法去做tracert的工作,那應該可以做到嗎?

祝你好運!

1

如果你想測試你是否可以連接到Web服務器上,你還可以創建一個基於主機名和端口號URL並用它來創建一個URLConnectionconnect method的檢查結果(包括異常)應告訴你網絡服務器是否可達。

5

首先你需要認識到你有潛在衝突的要求; IP套接字不是時間確定性的。您可以檢測到不可到達的最快速度是在您超時之後。您只能更快地檢測到可達性。

假設可達/ isReachable是你真正的目標,你應該只使用一個簡單的非阻塞IO插槽中所示的Java Ping模擬器,示例連接到時間服務,但將同樣很好地工作在8080

0

如果您需要在非常短的時間內對大量主機執行此操作,我會考慮使用fping之類的工具,以取而代之 - 在執行它並在返回時解析輸出。 fping一次運行大量的並行查詢,因此理論上可以在一分鐘內檢查幾千個主機(我認爲極限是4096?)

0

主機可用性的速率確定步驟不在您自己的代碼中,但在netlag。您必須等待主機迴應,這可能需要一些時間。如果你的程序在等待響應時阻塞,那可能是一個問題。我通過創建每個主機作爲對象來解決這個問題,每個主機都有自己的線程方法來檢查可用性。在我自己的情況下,我有40個主機我跟蹤。我的主程序每20秒循環一次40個機器對象的數組,每次調用適當的方法來檢查可用性。由於每個機器對象都有自己的線程來執行此操作,因此所有40臺機器都會同時被詢問,每個機器的響應時間(最長500毫秒)都不成問題。

相關問題