Secara amnya, kita hanya perlu menentukan sama ada satu mesin boleh mengakses (Ping) mesin lain Pada masa ini, kita hanya boleh menggunakan kelas java.net.InetAddress dalam perpustakaan kelas Java untuk mencapai ini dua kaedah untuk mengesan sama ada mesin jauh boleh dicapai
boolean isReachable(int timeout) // 测试地址是否可达 boolean isReachable(NetworkInterface netif, int ttl, int timeout) // 测试地址是否可达.
Ringkasnya, kaedah di atas adalah untuk membina objek InetAddress melalui alamat IP mesin jauh, dan kemudian memanggil kaedah isReachable untuk menguji rangkaian antara mesin panggilan dan mesin jauh. Ambil perhatian bahawa mesin jauh mungkin mempunyai berbilang alamat IP, jadi anda mungkin mahu menguji semua senario secara berulang.
void isAddressAvailable(String ip){ try{ InetAddress address = InetAddress.getByName(ip);//ping this IP if(address instanceof java.net.Inet4Address){ System.out.println(ip + " is ipv4 address"); }else if(address instanceof java.net.Inet6Address){ System.out.println(ip + " is ipv6 address"); }else{ System.out.println(ip + " is unrecongized"); } if(address.isReachable(5000)){ System.out.println("SUCCESS - ping " + IP + " with no interface specified"); }else{ System.out.println("FAILURE - ping " + IP + " with no interface specified"); } System.out.println("\n-------Trying different interfaces--------\n"); Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces(); while(netInterfaces.hasMoreElements()) { NetworkInterface ni = netInterfaces.nextElement(); System.out.println( "Checking interface, DisplayName:" + ni.getDisplayName() + ", Name:" + ni.getName()); if(address.isReachable(ni, 0, 5000)){ System.out.println("SUCCESS - ping " + ip); }else{ System.out.println("FAILURE - ping " + ip); } Enumeration<InetAddress> ips = ni.getInetAddresses(); while(ips.hasMoreElements()) { System.out.println("IP: " + ips.nextElement().getHostAddress()); } System.out.println("-------------------------------------------"); } }catch(Exception e){ System.out.println("error occurs."); e.printStackTrace(); } }
Keluaran program:
--------------START-------------- 10.13.20.70 is ipv4 address SUCCESS - ping 10.13.20.70 with no interface specified -------Trying different interfaces-------- Checking interface, DisplayName:MS TCP Loopback interface, Name:lo FAILURE - ping 10.13.20.70 IP: 127.0.0.1 ------------------------------------------- Checking interface, DisplayName:Intel(R) Centrino(R) Advanced-N 6200 AGN - Teefer2 Miniport, Name:eth0 FAILURE - ping 10.13.20.70 IP: 9.123.231.40 ------------------------------------------- Checking interface, DisplayName:Intel(R) 82577LM Gigabit Network Connection - Teefer2 Miniport, Name:eth2 SUCCESS - ping 10.13.20.70 ------------------------------------------- Checking interface, DisplayName:WAN (PPP/SLIP) Interface, Name:ppp0 SUCCESS - ping 10.13.20.70 IP: 10.0.50.189 ------------------------------------------- --------------END--------------
Seperti yang anda boleh lihat daripada di atas, penggunaan isReachable boleh digunakan untuk menentukan kebolehcapaian rangkaian jauh tanpa menyatakan sebarang antara muka, tetapi ini tidak dapat membezakan di mana paket data berasal dari antara muka rangkaian mana yang dihantar (jika terdapat berbilang antara muka rangkaian tempatan); rangkaian boleh menyambung ke.
Walau bagaimanapun, Java sendiri tidak menyediakan sebarang kaedah untuk menentukan alamat IP tempatan yang boleh disambungkan ke rangkaian jauh, dan antara muka pengaturcaraan rangkaian Java tidak menyediakan kaedah untuk mengakses paket data protokol ICMP, jadi data melalui rangkaian ICMP tidak dapat dicapai Ia juga mustahil untuk melaksanakan ini melalui pakej (sudah tentu ia boleh dicapai menggunakan JNI, tetapi ia bergantung pada platform sistem Pada masa ini, anda boleh mempertimbangkan kaedah yang dicadangkan dalam bahagian seterusnya ini). artikel.
Dalam sesetengah kes, kami mungkin ingin menentukan alamat rangkaian tempatan yang boleh disambungkan ke rangkaian jauh, supaya rangkaian jauh boleh menyambung kembali ke setempat untuk menggunakan perkhidmatan tertentu atau mengeluarkan pemberitahuan tertentu. Senario aplikasi biasa ialah perkhidmatan pemindahan fail (seperti FTP) dimulakan secara setempat, dan alamat IP tempatan perlu dihantar ke mesin jauh supaya mesin jauh boleh memuat turun fail melalui alamat ini atau mesin jauh menyediakan tertentu Perkhidmatan ini memberitahu mesin yang didaftarkan untuk mendapatkan peristiwa ini apabila peristiwa tertentu berlaku (biasa dalam bidang pengurusan sistem), jadi alamat tempatan yang boleh dihubungi (dari jauh) perlu disediakan semasa mendaftar.
Walaupun kami boleh menggunakan kaedah InetAddress.isReachabl untuk menentukan antara muka rangkaian tempatan yang boleh disambungkan kepada mainan jauh, ia tidak sesuai di sini kerana antara muka rangkaian tunggal boleh dikonfigurasikan dengan berbilang alamat IP. Kami boleh menggunakan Socket untuk mewujudkan sambungan TCP yang mungkin dan kemudian menentukan sama ada alamat IP tempatan boleh dicapai ke rangkaian jauh. Kami menggunakan kaedah sambung dalam kelas java.net.Socket
void connect(SocketAddress endpoint, int timeout) //使用Socket连接服务器,指定超时的时间
Kaedah ini memerlukan port jauh, yang boleh menjadi port mana-mana perkhidmatan terbuka berdasarkan protokol TCP (seperti Port perkhidmatan ECHO yang terbuka secara amnya 7, port perkhidmatan SSH Linux 22, dsb.). Malah, sambungan TCP yang telah ditetapkan diletakkan dalam baris gilir sambungan oleh timbunan protokol dan kemudian diedarkan kepada pelbagai perkhidmatan aplikasi yang sebenarnya memproses data Memandangkan UDP tidak mempunyai proses sambungan, perkhidmatan berasaskan UDP (seperti SNMP) tidak boleh diaplikasikan dalam kaedah ini.
Proses khusus adalah untuk menghitung setiap alamat rangkaian tempatan, mewujudkan Soket setempat, dan cuba menyambung ke alamat jauh pada port tertentu Jika ia boleh disambungkan, ini bermakna alamat setempat boleh mencapai rangkaian jauh.
void printReachableIP(InetAddress remoteAddr, int port){ String retIP = null; Enumeration<NetworkInterface> netInterfaces; try{ netInterfaces = NetworkInterface.getNetworkInterfaces(); while(netInterfaces.hasMoreElements()) { NetworkInterface ni = netInterfaces.nextElement(); Enumeration<InetAddress> localAddrs = ni.getInetAddresses(); while(localAddrs.hasMoreElements()){ InetAddress localAddr = localAddrs.nextElement(); if(isReachable(localAddr, remoteAddr, port, 5000)){ retIP = localAddr.getHostAddress(); break; } } } } catch(SocketException e) { System.out.println( "Error occurred while listing all the local network addresses."); } if(retIP == null){ System.out.println("NULL reachable local IP is found!"); }else{ System.out.println("Reachable local IP is found, it is " + retIP); } } boolean isReachable(InetAddress localInetAddr, InetAddress remoteInetAddr, int port, int timeout) { booleanisReachable = false; Socket socket = null; try{ socket = newSocket(); // 端口号设置为 0 表示在本地挑选一个可用端口进行连接 SocketAddress localSocketAddr = new InetSocketAddress(localInetAddr, 0); socket.bind(localSocketAddr); InetSocketAddress endpointSocketAddr = new InetSocketAddress(remoteInetAddr, port); socket.connect(endpointSocketAddr, timeout); System.out.println("SUCCESS - connection established! Local: " + localInetAddr.getHostAddress() + " remote: " + remoteInetAddr.getHostAddress() + " port" + port); isReachable = true; } catch(IOException e) { System.out.println("FAILRE - CAN not connect! Local: " + localInetAddr.getHostAddress() + " remote: " + remoteInetAddr.getHostAddress() + " port" + port); } finally{ if(socket != null) { try{ socket.close(); } catch(IOException e) { System.out.println("Error occurred while closing socket.."); } } } return isReachable; }
Hasil berjalan
--------------START-------------- FAILRE - CAN not connect! Local: 127.0.0.1 remote: 10.8.1.50 port22 FAILRE - CAN not connect! Local: 9.123.231.40 remote: 10.8.1.50 port22 SUCCESS - connection established! Local: 10.0.50.189 remote: 10.8.1.50 port22 Reachable local IP is found, it is 10.0.50.189 --------------END--------------
Apabila terdapat IPv4 dan IPv6 dalam persekitaran rangkaian, iaitu, apabila mesin mempunyai kedua-dua alamat IPv4 dan alamat IPv6, kita boleh membuat beberapa pengoptimuman kepada program, seperti
Memandangkan alamat IPv4 dan IPv6 tidak boleh mengakses satu sama lain, ia hanya perlu untuk menentukan kebolehcapaian antara alamat IPv4 dan antara alamat IPv6.
Anda tidak perlu membuat pertimbangan tentang alamat pemulangan IPv4 dan anda boleh melangkau ujian untuk alamat IPv6 Linklocal
Mengikut keperluan sebenar, Kami boleh memberi keutamaan untuk menggunakan IPv4 atau IPv6 untuk meningkatkan kecekapan pertimbangan
Hakim sama ada alamat setempat dan alamat jauh adalah IPv4 atau IPv6
// 判断是 IPv4 还是 IPv6 if(!((localInetAddr instanceofInet4Address) && (remoteInetAddr instanceofInet4Address) || (localInetAddr instanceofInet6Address) && (remoteInetAddr instanceofInet6Address))){ // 本地和远程不是同时是 IPv4 或者 IPv6,跳过这种情况,不作检测 break; }
Langkau alamat setempat dan alamat LinkLocal
if( localAddr.isLoopbackAddress() || localAddr.isAnyLocalAddress() || localAddr.isLinkLocalAddress() ){ // 地址为本地环回地址,跳过 break; }
Atas ialah kandungan terperinci Bagaimana untuk menguji sambungan rangkaian Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!