Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > Не пингуются хосты


Автор: Tsahes 19.12.2007, 11:54
Добрый день.
Кто-нибудь сталкивался с ситуацией, когда средствами java нельзя определить доступность хоста в сети?
Подскажите, в каком направлении следует искать?

Код

C:\>java -version
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b06)
Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode)


Код

C:\>ping google.com

Pinging google.com [64.233.187.99] with 32 bytes of data:

Reply from 64.233.187.99: bytes=32 time=139ms TTL=241
Reply from 64.233.187.99: bytes=32 time=141ms TTL=241
Reply from 64.233.187.99: bytes=32 time=139ms TTL=241
Reply from 64.233.187.99: bytes=32 time=140ms TTL=241

Ping statistics for 64.233.187.99:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 139ms, Maximum = 141ms, Average = 139ms


И сам пример получения информации доступности:
Код

import java.net.InetAddress;
import java.security.Security;

public class PingMaker {

    public static void main(String[] args) {
        try {
            final String[] hosts = { "google.com" };

            int linkStatusTimeout = 300;

            for (String host : hosts) {
                InetAddress ip = InetAddress.getByName(host);

                System.out.println("ping " + host + " [" + ip + "] timeout "
                    + linkStatusTimeout);

                boolean pingStatus = ip.isReachable(linkStatusTimeout * 1000);
                if (pingStatus) {
                    System.out.println("available");
                }
                else {
                    System.out.println("not available");
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}


Результат:
Код

ping google.com [google.com/72.14.207.99] timeout 300
not available

Автор: Tsahes 19.12.2007, 14:10
Цитата(Tsahes @ 19.12.2007,  11:54)
средствами java нельзя определить доступность хоста в сети

Проблема локализировалась.
Удалось выяснить, что доступность хостов успешно определяется для jre1.5.0.
Для jre1.6.0 (jre1.6.0_01, jre1.6.0_02) ни одного положительного ответа получено не было.
В чем могут быть причины?

Автор: AlexeyVorotnikov 19.12.2007, 15:18
Причины могут быть в различной реализации этого метода в различных версиях JDK.

Автор: Tsahes 19.12.2007, 18:02
Цитата(AlexeyVorotnikov @ 19.12.2007,  15:18)
Причины могут быть в различной реализации этого метода в различных версиях JDK.

Это только констатация smile 
Возможно, кто нибудь сталкивался с необходимостью решения проблемы?

Дальше - больше.
Для jdk1.5.0_11 мне не удалось подобрать ни одного значение IP-адреса такое, чтобы метод
Код

byte[] ip = new byte[] {..., ..., ..., ...};
InetAddress ip = InetAddress.getByAddress(ip);
boolean pingStatus = ip.isReachable(300 * 1000);

возвращал false  smile
Естественно, я параллельно проверял ping`ом из консоли.

Люди, помогите мне!

Автор: serger 19.12.2007, 18:23
Я для решения проблемы проверял порт бд напрямую.. заодно проверял доступность бд.
Ни один из примеров пинга меня не устроил..

Хотя вориант с версиями JDK интересен, возможно из-за этого у меня и не работало.

Автор: dual 3.1.2008, 15:45
Не помню, где нашел этот код...

Код

/*
 * PingICMP.java
 *
 * Created on 17 Декабрь 2007 г., 15:06
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package ping;

import java.io.IOException;
import java.net.InetAddress;
/**
 *  This class provides a way to sending ICMP (RFC792) ECHO request and
 *  receiving ECHO response. Since on all modern operating systems this would
 *  require access to raw sockets and java has currently no such access this is
 *  implemented by executing operating system's ping command with system
 *  specific parameters Currently only Unix (including Linux,MacOSX) and windows
 *  are supported. Older MacOSes are not supported because I have no idea how tu
 *  ping under MacOSes.
 *  <H3>Requirements:</h3>
 *  <ul>
 *    <li> ping has to be in your PATH environment variable</li>
 *    <li> you have to have permission to execute ping</li>
 *  </ul>
 *  <h3>About timeout</h3>
 *  Under win32 it's easy to set timeout for pings - you
 *  use -w parameter but on UNIX there is no option to set timeout, so we have
 *  to simulate its behaviour somehow.<br>
 *  This is done by simply executing ping command and checking its state by
 *  method Process.exitValue(), wich throws IllegalThreadStateException if the
 *  command is still running. Process' state is checked every 500ms. Note that
 *  ping method can return earlier than <i>timeout</i> when ping command's
 *  internal timeout is reached.
 *
 *@author     Rafal Krupinski
 *@created    26 september 2003
 *@version    $Id$
 */

public final class PingICMP {

    /**
     *  This is basic method for pinging host. It checks your system's name and
     *  timeout value and calls aprioprate method, wich executes ping command
     *
     *@param  target                    host name or IP (v4) to ping
     *@param  count                     number of pingecho packets to send
     *@param  timeout                   time to wait on ping responses, see above.
     *@return                           true if target host is reachable; false
     *      otherwise
     *@exception  IOException           if an I/O error occurs
     *@exception  InterruptedException  if the current thread is interrupted by
     *      another thread while it is waiting, then the wait is ended and an
     *      InterruptedException is thrown.
     */
    public static boolean ping(String target, int count, long timeout)
        throws IOException, InterruptedException {
        String os = System.getProperty("os.name");
        if (os.startsWith("Windows")) {
            return pingWin(target, count, timeout);
        }
        //if(os.startsWith("Mac OS")){return pingMac(target,count,timeout);}
        else {
            if (timeout != 0) {
                return pingUnix(target, count, timeout);
            }
            else {
                return pingUnix(target, count);
            }
        }
    }


    /**
     *  This is the same as ping(target,count,0) timeout value is system specific;
     *  probably you shouldn't use this method
     *
     *@param  target                    host name or IP (v4) to ping
     *@param  count                     number of pingecho packets to send
     *@return                           true if target host is reachable; false
     *      otherwise
     *@exception  IOException           if an I/O error occurs
     *@exception  InterruptedException  if the current thread is interrupted by
     *      another thread while it is waiting, then the wait is ended and an
     *      InterruptedException is thrown.
     */
    public static boolean ping(String target, int count)
        throws IOException, InterruptedException {
        return ping(target, count, 0);
    }

    private static boolean pingWin(String target, int count, long timeout)
        throws IOException, InterruptedException {
        String[] cmd = {};
        if (timeout == 0) {
            cmd = new String[4];
        }
        else {
            cmd = new String[6];
            cmd[3] = "-w";
            cmd[4] = Long.toString(timeout);
        }
        cmd[0] = "ping";
        cmd[1] = "-n";
        cmd[2] = Integer.toString(count);
        cmd[cmd.length - 1] = target;
        return ping(cmd);
    }


//miliseconds in second
    private final static long SECMSEC = 1000;

//delay between checks
    private final static long DELAY = 500;

    private static boolean pingUnix(String target, int count, long timeout)
        throws IOException, InterruptedException {
        Process ping = Runtime.getRuntime().exec(new String[]{"ping", "-c", Integer.toString(count),target});
        //sleep until we can expect result, ie. DELAY or temeout after last ping, whichever comes sooner
        long sleep = count * SECMSEC - 1 + Math.min(timeout, DELAY);
        timeout -= Math.min(timeout, DELAY);
        Thread.sleep(sleep);
        //if initial timeout was less than DELAY than timeout is already 0, but still we must check status
        do {
            //this makes timeout is always nonnegative
            timeout -= Math.min(timeout, DELAY);
            Thread.sleep(timeout);
            try {
                return ping.exitValue() == 0;
            }
            catch (IllegalThreadStateException e) {
                /*
                 *  process still running; do nothing; wait another DELAYms
                 */
            }
        } while (timeout > 0);
        //timeout reached
        return false;
    }

    private static boolean pingUnix(String target, int count)
        throws IOException, InterruptedException {
        return ping(new String[]{"ping", "-c", Integer.toString(count), target});
    }

    private static boolean ping(String[] cmd)
        throws IOException, InterruptedException {
        Process ping = Runtime.getRuntime().exec(cmd);
        return ping.waitFor() == 0;
    }
}


Код

package ping;

import java.io.IOException;

public class Main {
    
    public Main() {
    }
    
    public static void main(String[] args) {
        try {
            if( PingICMP.ping("22.22.22.22", 3) )
                System.out.println("ping succsessfull");
            else
                System.out.println("ping unsuccsessfull");
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
    
}


Автор: w1nd 4.1.2008, 02:47
Tsahes, если вам нужно проверить доступность сетевого сервиса, попробуйте к нему подключиться. Всего делов. 

А такие вещи, как imcp ping могут не работать и для доступных хостов - это всё может блокироваться брандмауэром (и блокируется). Железный результат даст разве что полное сканирование, но такие действия свойственны хакерам, со всеми вытекающими smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)