InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
왜 isReachable
돌아 오나요 false
? IP를 핑할 수 있습니다.
InetAddress byName = InetAddress.getByName("173.39.161.140");
System.out.println(byName);
System.out.println(byName.isReachable(1000));
왜 isReachable
돌아 오나요 false
? IP를 핑할 수 있습니다.
답변:
"의 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);
ping 의 -c 옵션을 사용하면 ping이 서버에 한 번만 도달하려고 시도 할 수 있습니다 (터미널에서 사용하던 무한 핑과는 반대로).
호스트에 연결할 수 있으면 0 을 반환 합니다. 그렇지 않으면 반환 값으로 "2"가 표시됩니다.
훨씬 간단하지만 물론 플랫폼에 따라 다릅니다. 이 명령을 사용하는 데 특정 권한 경고가있을 수 있지만 내 컴퓨터에서 작동합니다.
참고 : 1)이 솔루션은 생산 품질이 아닙니다. 약간의 해킹입니다. Google이 다운되거나 인터넷이 일시적으로 느리거나 권한 / 시스템 설정에 약간의 재미가 있더라도 거짓 부정을 반환 할 수 있습니다 (즉, 입력 주소에 도달 할 수 있어도 실패 할 수 있음). 2) isReachable 실패는 미해결 문제입니다. 다시 말하지만, JVM이 호스트에 도달하려고 시도하는 방식으로 인해이 글을 쓰는 시점에 "완벽한"방법이 없음을 나타내는 여러 온라인 리소스가 있습니다.이 작업은 본질적으로 간단하지만 플랫폼 별 작업이라고 생각합니다. , 아직 JVM에 의해 충분히 추상화되지 않았습니다.
isReachable
실패하고 ping을 사용하여 icmp가 허용되지 않습니까? 지금 어떻게 처리해야하는지 아십니까?
public boolean waitFor(long timeout, TimeUnit unit)
in java.lang.Process (@since 1.8)
나는이 같은 질문에 대한 답을 얻기 위해 여기에 왔지만 플랫폼 독립적 인 솔루션을 찾고 있었기 때문에 답이 만족스럽지 않았습니다. 다음은 내가 작성한 코드이며 플랫폼에 독립적이지만 다른 시스템의 열린 포트에 대한 정보가 필요합니다 (대부분의 시간이 있음).
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;
}
}
InetAddress.isReachable()
포트 7을 통해 이미 수행 한 작업 과 동일합니다 . 단, 후자는 IOExceptions
도달 가능성 측면에서 가능한 다양한 의미에 대해 더 지능적 입니다.
InetAddress.isReachable()
표준 라이브러리에 포트 인수를 포함하도록 오버로드 되면 좋을 것이라고 생각합니다 . 왜 포함되지 않았는지 궁금합니다.
인터넷에 연결되어 있는지 만 확인하려면이 방법을 사용합니다. 인터넷이 연결되어 있으면 true를 반환합니다. 프로그램을 통해 연결하려는 사이트의 주소를 사용하는 것이 좋습니다.
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;
}
2012 년에 원래 질문을 받았을 때 주가 무엇인지 잘 모르겠습니다.
현재로서는 ping이 루트로 실행됩니다. ping 실행 파일의 인증을 통해 + s 플래그와 루트에 속한 프로세스를 볼 수 있습니다. 즉, 루트로 실행됩니다. ping이있는 위치에서 ls -liat를 실행하면 볼 수 있습니다.
따라서 InetAddress.getByName ( "www.google.com"). isReacheable (5000)을 루트로 실행하면 true를 반환해야합니다.
ICMP (ping에서 사용하는 프로토콜)에서 사용하는 원시 소켓에 대한 적절한 인증이 필요합니다.
InetAddress.getByName은 ping만큼 안정적이지만 제대로 실행하려면 프로세스에 대한 적절한 권한이 필요합니다.
인터넷 연결을 테스트하는 유일한 신뢰할 수있는 방법은 실제로 연결하고 파일을 다운로드하거나 exec ()를 통해 OS 핑 호출의 출력을 구문 분석하는 것입니다. ping에 대한 종료 코드에 의존 할 수 없으며 isReachable ()은 쓰레기입니다.
ping 명령이 올바르게 실행되면 0을 반환하므로 ping 종료 코드를 신뢰할 수 없습니다. 안타깝게도 ping은 대상 호스트에 도달 할 수 없지만 홈 ADSL 라우터에서 "Destination host unreachable"을 받으면 올바르게 실행됩니다. 이것은 성공적인 히트로 취급되는 일종의 응답이므로 종료 코드 = 0입니다. 이것이 Windows 시스템에 있음을 추가해야합니다. 확인되지 않음 * nixes.
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은 사용중인 네트워크가 있거나 시스템이 더 큰 nping 번호를 선택하는 경우 ip (패킷) ping을 시도하는 횟수입니다.
wping은 ip에서 pong을 기다리는 시간입니다.
이 방법을 사용하여 2000ms 로 설정할 수 있습니다.
isReachable(5, 2000, "192.168.7.93");
또는 다음과 같이 사용하십시오.
public static boolean exists(final String host)
{
try
{
InetAddress.getByName(host);
return true;
}
catch (final UnknownHostException exception)
{
exception.printStackTrace();
// Handler
}
return false;
}
컴퓨터를 ping 할 수 있으므로 Java 프로세스는 검사를 수행 할 수있는 충분한 권한으로 실행되어야합니다. 아마도 더 낮은 범위의 포트를 사용했기 때문일 것입니다. sudo / superuser로 Java 프로그램을 실행하면 작동 할 것입니다.