जब मैं IP पता पिंग कर सकता हूं तो InetAddress.isReachable क्यों गलत है?


96
InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));

क्यों isReachableलौटता है false? मैं आईपी पिंग कर सकता हूं।


संभावित डुप्लिकेट: stackoverflow.com/questions/4779367/…
assylias

1
यह इसी तरह की है। लेकिन मुझे इस समस्या को हल करने के लिए कोई सुराग नहीं मिला। तो मैंने इसे यहाँ reraised किया। अपने अनुस्मारक के लिए धन्यवाद!
जियाफू

2
मैं टाइमआउट बढ़ाने की कोशिश करूंगा।
jayunit100

यह एक बहुत अच्छा प्रश्न है, इसके साथ पर्याप्त उत्थान नहीं है। एकमात्र ऐसा ही प्रश्न मुझे मिला, जिसे क्लोजर प्रश्न के रूप में चिह्नित किया गया था और उत्तर अनिर्णायक था।
jayunit100

3
क्या कोई मुझे बता सकता है कि वास्तव में क्या पहुंच योग्य () है? यह मुझे लोकलहोस्ट पर भी झूठे लौटाता है ...
सेठ केनो

जवाबों:


73

"IsReachable" विधि कई मामलों में मेरे लिए का उपयोग कर के लायक नहीं किया गया है। यदि आप ऑनलाइन हैं और बाहरी मेजबानों (यानी google.com) को हल करने में सक्षम हैं, तो आप बस परीक्षण के लिए मेरा विकल्प देखने के लिए नीचे स्क्रॉल कर सकते हैं ... जो आमतौर पर * NIX मशीनों पर काम करने लगता है।

समस्या

इस बारे में बकबक करने वाले बहुत है:

भाग 1: समस्या का एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण

ध्यान दें कि इस मामले में, यह विफल रहता है।

       //also, this fails for an invalid address, like "www.sjdosgoogle.com1234sd" 
       InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
      for (InetAddress address : addresses) {
        if (address.isReachable(10000))
        {   
           System.out.println("Connected "+ address);
        }
        else
        {
           System.out.println("Failed "+address);
        }
      }
          //output:*Failed www.google.com/74.125.227.114*

भाग 2: एक हैकिश वर्कअराउंड

एक विकल्प के रूप में, आप यह कर सकते हैं:

// in case of Linux change the 'n' to 'c'
    Process p1 = java.lang.Runtime.getRuntime().exec("ping -n 1 www.google.com");
    int returnVal = p1.waitFor();
    boolean reachable = (returnVal==0);

का -c विकल्प पिंग पिंग को बस एक बार सर्वर तक पहुंचने की कोशिश करेगा (अनंत पिंग के विपरीत जो हम टर्मिनल पर उपयोग करने के लिए उपयोग किया जाता है)।

यदि होस्ट फिर से उपलब्ध हो, तो यह 0 पर वापस आ जाएगा । अन्यथा, आपको "2" रिटर्न वैल्यू के रूप में मिलेगा।

बहुत सरल - लेकिन निश्चित रूप से यह मंच विशिष्ट है। और इस आदेश का उपयोग करने के लिए कुछ विशेष विशेषाधिकार हो सकते हैं - लेकिन मुझे लगता है कि यह मेरी मशीनों पर काम करता है।


कृपया ध्यान दें कि: 1) यह समाधान उत्पादन गुणवत्ता नहीं है। इसकी एक बिट है। यदि Google डाउन है, या आपका इंटरनेट अस्थायी रूप से धीमा है, या हो सकता है कि आपके विशेषाधिकारों / सिस्टम सेटिंग्स में कुछ फनीनेस होने पर भी, यदि गलत निगेटिव वापस किया जा सकता है (यानी यह इनपुट एड्रेस के उपलब्ध होने के बावजूद भी विफल हो सकता है)। 2) isReachable विफलता एक उत्कृष्ट मुद्दा है। फिर से - कई ऑनलाइन संसाधनों से संकेत मिलता है कि इस लेखन के समय ऐसा करने का कोई "सही" तरीका नहीं है, जिस तरह से जेवीएम मेजबानों तक पहुंचने की कोशिश करता है - मुझे लगता है कि यह एक आंतरिक रूप से मंच विशिष्ट कार्य है, जो हालांकि सरल है , अभी तक JVM द्वारा पर्याप्त रूप से सार नहीं किया गया है।


@ jayunit100 न तो दृष्टिकोण के लिए काम कर रहा है, isReachableमैं असफल हो रहा हूं और पिंग का उपयोग कर रहा हूं , जिसे आईसीएमपी की अनुमति नहीं है? क्या आप जानते हैं कि अब इससे कैसे निपटना है?
युवी

6
@ युवी यदि आप विंडोज का उपयोग कर रहे हैं, तो झंडे अलग हैं। इसके बजाय -c आप चाहते हैं -n।
जेम्स टी स्नेल

WaitFor () को वापस लौटने में 10 सेकंड लगते हैं। क्या जावा 7 में टाइमआउट का उल्लेख करने का कोई तरीका है?
जयदेव

@ जयदेव, एक अतिभारित विकल्प भी है: public boolean waitFor(long timeout, TimeUnit unit)java.lang.Process (@since 1.8) में
अविभाजित

2020-01 तक मैं किसी भी समस्या के बिना समस्या के उदाहरण को चला सकता हूं, यह एक आईपीवी 4 और एक आईपीवी 6 पते के लिए "कनेक्टेड" रिपोर्ट करता है। बग भी जावा 5.0 B22 में तय हो गई है। शायद isReachableअब और अधिक विश्वसनीय है दिन।
Lii

54

मैं इसी सवाल का जवाब पाने के लिए यहां आया था, लेकिन मैं किसी भी जवाब से असंतुष्ट था क्योंकि मैं एक मंच स्वतंत्र समाधान की तलाश में था। यहाँ वह कोड है जो मैंने लिखा है और प्लेटफ़ॉर्म स्वतंत्र है, लेकिन अन्य मशीन पर किसी भी खुले पोर्ट के बारे में जानकारी की आवश्यकता है (जो कि हमारे पास अधिकांश समय है)।

private static boolean isReachable(String addr, int openPort, int timeOutMillis) {
    // Any Open port on other machine
    // openPort =  22 - ssh, 80 or 443 - webserver, 25 - mailserver etc.
    try {
        try (Socket soc = new Socket()) {
            soc.connect(new InetSocketAddress(addr, openPort), timeOutMillis);
        }
        return true;
    } catch (IOException ex) {
        return false;
    }
}

2
यह एक महान मंच स्वतंत्र समाधान है, धन्यवाद!
ivandov

1
मुझे खुशी है कि मैं यहीं खत्म हो गया, सौरभ के सोचने का अच्छा तरीका :)
JustADev

तो, बस यह सुनिश्चित करने के लिए कि मैं पूरी तरह से समझता हूं: जब तक कोई अपवाद नहीं है, तब तक पता उपलब्ध नहीं था?
टिम्मीज93

1
यह InetAddress.isReachable()पोर्ट 7 के माध्यम से पहले से ही जैसा है, वैसा ही है, सिवाय इसके कि उत्तरार्ध अधिक बुद्धिमान है, जो कि IOExceptionsअभिकर्मक के रूप में विभिन्न संभावित अर्थों के बारे में है।
लोरने का मार्स

1
हां @EJP मुझे लगता है कि यह बहुत अच्छा होगा अगर InetAddress.isReachable()इसे पोर्ट लॉजिक में शामिल करने के लिए ओवरलोड किया गया था, मानक पुस्तकालय में। मुझे आश्चर्य है कि इसे शामिल क्यों नहीं किया गया?
सौरभ भट

7

यदि आप केवल यह जांचना चाहते हैं कि क्या यह इंटरनेट उपयोग करने के लिए जुड़ा हुआ है या नहीं, तो यह सही है अगर इंटरनेट जुड़ा है, तो यह बेहतर है यदि आप उस साइट के पते का उपयोग करते हैं जिसे आप प्रोग्राम के माध्यम से कनेक्ट करने का प्रयास कर रहे हैं।

     public static boolean isInternetReachable()
    {
        try {
            //make a URL to a known source
            URL url = new URL("http://www.google.com");

            //open a connection to that source
            HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();

            //trying to retrieve data from the source. If there
            //is no connection, this line will fail
            Object objData = urlConnect.getContent();

        } catch (Exception e) {              
            e.printStackTrace();
            return false;
        }

        return true;
    }

2
बेकार अगर सर्वर में एक वेब सर्वर नहीं है, तो यह सवाल में निर्दिष्ट शर्त नहीं है।
Fran Marzoa

3

बस इसका उल्लेख स्पष्ट रूप से अन्य उत्तरों के बाद से नहीं है। IsReachable () के पिंग भाग को यूनिक्स पर रूट एक्सेस की आवश्यकता होती है। और जैसा कि 4779367 में bestsss द्वारा बताया गया है :

और अगर आप पूछते हैं कि बैश से पिंग क्यों नहीं होता है, तो वास्तव में इसकी आवश्यकता भी है। उस ls -l / bin / ping को करें।

चूंकि रूट का उपयोग करना मेरे मामले में कोई विकल्प नहीं था, इसलिए समाधान यह था कि जिस विशिष्ट सर्वर में मेरी रुचि थी, उसके लिए फ़ायरवॉल में पोर्ट 7 तक पहुंच की अनुमति दी जाए।


3

मुझे यकीन नहीं है कि 2012 में जब मूल प्रश्न वापस पूछा गया था तो वह कौन सा राज्य था।

जैसा कि यह अब खड़ा है, पिंग को एक जड़ के रूप में निष्पादित किया जाएगा। पिंग निष्पादन योग्य प्राधिकरण के माध्यम से आप + s ध्वज देखेंगे, और रूट से संबंधित प्रक्रिया, जिसका अर्थ है कि यह रूट के रूप में चलेगा। ls -liat चलाएँ जहाँ पिंग स्थित है और आपको इसे देखना चाहिए।

इसलिए, यदि आप InetAddress.getByName ("www.google.com") चलाते हैं। isReacheable (5000) को रूट के रूप में, यह सही लौटना चाहिए।

आपको कच्चे सॉकेट के लिए उचित प्राधिकरण की आवश्यकता है, जिसका उपयोग ICMP द्वारा किया जाता है (पिंग द्वारा प्रयुक्त प्रोटोकॉल)

InetAddress.getByName पिंग के रूप में विश्वसनीय है, लेकिन आपको इसे ठीक से चलाने के लिए प्रक्रिया की उचित अनुमति चाहिए।


0

मेरा सुझाव है कि इंटरनेट कनेक्शन का परीक्षण करने का एकमात्र विश्वसनीय तरीका वास्तव में एक फ़ाइल को कनेक्ट करना और डाउनलोड करना है, या निष्पादन के माध्यम से ओएस पिंग कॉल के आउटपुट को पार्स करना है। आप पिंग और isReachable () बकवास के लिए निकास कोड पर भरोसा नहीं कर सकते।

यदि पिंग कमांड सही तरीके से निष्पादित होती है तो आप एक पिंग एग्जिट कोड पर भरोसा नहीं कर सकते हैं। दुर्भाग्य से, पिंग सही ढंग से निष्पादित होता है अगर यह लक्ष्य होस्ट तक नहीं पहुंच सकता है, लेकिन आपके घर एडीएसएल राउटर से "गंतव्य मेजबान पहुंच से बाहर है"। यह एक उत्तर की तरह है जो एक सफल हिट के रूप में माना जाता है, इस प्रकार बाहर निकलें कोड = 0. जोड़ना होगा हालांकि यह एक विंडोज सिस्टम पर है। चेक नहीं किया गया * निक्स।


0
 private boolean isReachable(int nping, int wping, String ipping) throws Exception {

    int nReceived = 0;
    int nLost = 0;

    Runtime runtime = Runtime.getRuntime();
    Process process = runtime.exec("ping -n " + nping + " -w " + wping + " " + ipping);
    Scanner scanner = new Scanner(process.getInputStream());
    process.waitFor();
    ArrayList<String> strings = new ArrayList<>();
    String data = "";
    //
    while (scanner.hasNextLine()) {
        String string = scanner.nextLine();
        data = data + string + "\n";
        strings.add(string);
    }

    if (data.contains("IP address must be specified.")
            || (data.contains("Ping request could not find host " + ipping + ".")
            || data.contains("Please check the name and try again."))) {
        throw new Exception(data);
    } else if (nping > strings.size()) {
        throw new Exception(data);
    }

    int index = 2;

    for (int i = index; i < nping + index; i++) {
        String string = strings.get(i);
        if (string.contains("Destination host unreachable.")) {
            nLost++;
        } else if (string.contains("Request timed out.")) {
            nLost++;
        } else if (string.contains("bytes") && string.contains("time") && string.contains("TTL")) {
            nReceived++;
        } else {
        }
    }

    return nReceived > 0;
}

आईपी ​​(पैकेट) को पिंग करने के लिए nping की संख्या है, यदि आपके पास व्यस्त नेटवर्क है या सिस्टम बड़े नपिंग नंबर चुनते हैं।
wping आईपी से पोंग के लिए समय की प्रतीक्षा कर रहा है, आप इसे
इस विधि का उपयोग करने के लिए 2000ms सेट कर सकते हैं u इसे लिख सकते हैं:

isReachable(5, 2000, "192.168.7.93");

संभावित कमांड इंजेक्शन, इसे चलाने से पहले स्ट्रिंग इनपुट को मान्य करना सुनिश्चित करें
जासूसी

"सामान्य विफलता" त्रुटि संदेश भी है। यह भी विंडोज़ विशिष्ट जैसा दिखता है। मुझे पूरा यकीन है कि ये त्रुटि संदेश विभिन्न भाषाओं में स्थानीयकृत हैं, इसलिए सुपर पोर्टेबल नहीं हैं।
जासूसी

यह विंडोज़ सिस्टम के लिए है।
अर्मिन मोकरी

हाँ, मैं इसे पहले खिड़कियों पर देखा है
जासूसी

0

या इस तरह से उपयोग कर रहे हैं:

public static boolean exists(final String host)
{
   try
   {
      InetAddress.getByName(host);
      return true;
   }
   catch (final UnknownHostException exception)
   {
      exception.printStackTrace();
      // Handler
   }
   return false;
}

0

InetAddress.isReachable परतदार है, और कभी-कभी उन पतों के लिए अप्राप्य हो जाता है जिन्हें हम पिंग कर सकते हैं।

मैंने निम्नलिखित कोशिश की:

ping -c 1 <fqdn> और जाँच करें exit status

उन सभी मामलों के लिए InetAddress.isReachableकाम करता है जहाँ मैंने कोशिश की थी जहाँ काम नहीं करता है।


-1

चूंकि आप कंप्यूटर को पिंग कर सकते हैं, इसलिए आपकी जावा प्रक्रिया को चेक करने के लिए पर्याप्त विशेषाधिकार के साथ चलना चाहिए। संभवतः निचली सीमा में बंदरगाहों के उपयोग के कारण। यदि आप sudo / superuser के साथ अपना जावा प्रोग्राम चलाते हैं, तो मैं शर्त लगाता हूं कि यह काम करेगा।


आपको कम रेंज में बंदरगाहों से जुड़ने के लिए विशेषाधिकार की आवश्यकता नहीं है ।
लोर्ने
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.