2008-10-12 16 views
11

मुझे सबसे तेज़ और सबसे सटीक फ़ंक्शन boolean isReachable(String host, int port) चाहिए जो नीचे दी गई शर्तों के तहत निम्न JUnit परीक्षण पास करता है। टाइमआउट मान JUnit परीक्षण द्वारा स्वयं निर्दिष्ट किए जाते हैं, और उन्हें "पहुंच योग्य" माना जा सकता है।जावा में पहुंचने योग्य होस्ट का पता लगाने का सबसे तेज़ तरीका क्या है?

कृपया ध्यान दें: सभी उत्तरों प्लेटफ़ॉर्म-स्वतंत्र होना चाहिए। इसका मतलब है कि InetAddress.isReachable(int timeout) काम नहीं करेगा, क्योंकि यह पोर्ट पर एक पिंग करने के लिए पोर्ट 7 पर निर्भर करता है (आईसीएमपी पिंग विंडोज पर एक अनियंत्रित फ़ंक्शन है), और इस पोर्ट को इस सेटअप में अवरुद्ध कर दिया गया है।

लैन सेटअप:

  • thisMachine (192.168.0.100)
  • otherMachine (192.168.0.200)
  • कोई मशीन noMachine कहा जाता है या आईपी 192.168.0.222 (हमेशा पहुंच योग्य नहीं)
  • दोनों मशीनों द्वारा चलाए जा रहे है पोर्ट 8080 पर अपाचे टॉमकैट; अन्य सभी बंदरगाहों तक नहीं पहुंचा जा
  • example.com (208.77.188.166) बंदरगाह 80 पर एक वेबसर्वर चल रहा है और जब लैन

कभी कभी इंटरनेट से जुड़ा है केवल पहुंचा जा सकता है है (पोर्ट 7 सहित), लैन से काट दिया जाता है इंटरनेट जिस मामले में केवल आईपी पते द्वारा बुलाया जाने वाला स्थानीय मशीन पहुंच योग्य है (अन्य सभी पहुंच योग्य नहीं हैं; कोई 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. 
} 

निम्न परीक्षण केवल चलाने जब लैन इंटरनेट से जुड़ा है।

@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

मेरा सबसे हाल ही समाधान एक TimedSocket (source code) का उपयोग कर एक कनेक्ट करते समय के साथ 3000ms समय-समाप्त निर्भर करता है।

समय:

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

यहां तक ​​कि इन ठीक से काम करने के लिए मिल नहीं कर सकता:

  • testNoDNS()
  • testHaveDNS()
0

यह सुनिश्चित नहीं है कि यह कितना व्यावहारिक है।

ट्रैसरआउट (विंडोज़ पर ट्रैकर्ट) के बराबर करने के बारे में और एक बार सफलता मिलने के बाद, आप आगे बढ़ सकते हैं।

कॉर्पोरेट नेटवर्क में, मैंने आईसीएमपी (पिंग) को व्यवस्थापक द्वारा अवरुद्ध देखा है लेकिन आमतौर पर, ट्रैकर्ट अभी भी काम करता है। यदि आप ट्रैकर्र्ट करने के लिए एक त्वरित तरीका समझ सकते हैं, तो यह चाल चलनी चाहिए?

गुड लक!

1

आप परीक्षण करते हैं कि आप भी एक URL होस्ट नाम और पोर्ट संख्या के आधार पर बना सकते हैं एक वेब सर्वर से कनेक्ट कर सकते हैं और उसका उपयोग एक URLConnectionconnect method की (अपवाद सहित) परिणाम जाँच बनाने के लिए करना चाहते हैं चाहिए आपको बताएं कि वेबसर्वर पहुंच योग्य है या नहीं।

5

सबसे पहले आपको यह पहचानने की आवश्यकता है कि आपके पास संभावित विरोधी आवश्यकताओं है; आईपी ​​सॉकेट समय निर्धारित नहीं हैं। सबसे तेज़ आप कभी भी अप्राप्यता का पता लगा सकते हैं, आपके विलुप्त होने के बाद। आप केवल पहुंच योग्यता का पता लगा सकते हैं।

गम्यता मान लिया जाये कि/isReachable अपने वास्तविक उद्देश्य, तुम बस, उदाहरण के समय सेवा से कनेक्ट करती है Java Ping सिम्युलेटर में दिखाया गया है का उपयोग करना चाहिए एक सीधा गैर अवरुद्ध सॉकेट आईओ लेकिन 8080 के

0

पर अच्छी तरह से समान रूप से काम करेगा है यदि आपको बहुत ही कम समय में मेजबानों की गंभीरता से बड़ी संख्या में ऐसा करने की आवश्यकता है, तो मैं fping जैसे टूल का उपयोग करने पर विचार करता हूं- इसे निष्पादित करने के लिए खोलें और आउटपुट को वापस आने पर पार्स करें। फिंग एक बार में समानांतर प्रश्नों की एक बड़ी संख्या चलाता है, इसलिए आप सैद्धांतिक रूप से एक मिनट में कुछ हज़ार होस्ट देख सकते हैं (मुझे लगता है कि सीमा 4096 है?)

0

होस्ट उपलब्धता के लिए चरण निर्धारित करने की दर आपके कोड के भीतर नहीं है, लेकिन नेटलाग में। मेजबान को जवाब देने के लिए आपको इंतजार करना होगा, और इसमें समय लग सकता है। यदि प्रतिक्रिया के लिए प्रतीक्षा करते समय आपका प्रोग्राम ब्लॉक करता है तो यह एक समस्या हो सकती है। मैं प्रत्येक होस्ट को ऑब्जेक्ट के रूप में बनाकर, प्रत्येक को उपलब्धता की जांच के लिए अपनी स्वयं की थ्रेडेड विधि के साथ मिला। मेरी अपनी स्थिति में मेरे पास 40 मेजबान हैं जिनके बारे में मैं ट्रैक करता हूं। मेरा मुख्य कार्यक्रम प्रत्येक 20 सेकंड में 40 मशीन ऑब्जेक्ट्स की एक सरणी के माध्यम से loops, उपलब्धता की जांच करने के लिए प्रत्येक पर उपयुक्त विधि बुला रहा है। चूंकि प्रत्येक मशीन ऑब्जेक्ट ऐसा करने के लिए अपने स्वयं के धागे को जन्म देता है, इसलिए सभी 40 मशीनों को समवर्ती रूप से पूछताछ की जाती है और प्रत्येक के लिए (500ms तक) प्रतिक्रिया समय कोई समस्या नहीं है।

संबंधित मुद्दे