如何使用Java获取连接到同一子网的设备的IP地址列表?
如何使用Java获取连接到同一子网的设备的IP地址列表?
如果您的网络主机对 ICMP 包(ping)做出响应(JDK 5 及以上版本),则此方法应该有效:
public void checkHosts(String subnet){
int timeout=1000;
for (int i=1;i<255;i++){
String host=subnet + "." + i;
if (InetAddress.getByName(host).isReachable(timeout)){
System.out.println(host + " is reachable");
}
}
}
可以像这样为子网(192.168.0.1-254)调用方法:
checkHosts("192.168.0");
没有测试过,但应该像这样工作。显然,这只检查 IP 地址的最后一个字节中的 254 个主机...
检查:
http://download-llnw.oracle.com/javase/6/docs/api/java/net/InetAddress.html#isReachable%28int%29 http://blog.taragana.com/index.php/archive/how-to-do-icmp-ping-in-java-jdk-15-and-above/
希望能有所帮助。
要列出连接在局域网中的主机,您需要对子网上所有可用的IP地址进行ping。但是,ping消息可能会受到防火墙的限制,因此更安全的方法是打开到局域网IP地址范围内每个IP地址的套接字。
import java.net.InetAddress;
public class Main {
public static void main(String[] args) throws Exception{
long initialT = System.currentTimeMillis();
checkHosts("192.168.0");
long finalT = System.currentTimeMillis();
System.out.println("Scan Completed taking " + (finalT - initialT) + " miliseconds approximately!");
}
public static void checkHosts(String subnet) throws Exception{
int timeout=1000;
for (int i=1;i<255;i++){
String host=subnet + "." + i;
if (InetAddress.getByName(host).isReachable(timeout)){
System.out.println(host + " is reachable");
}
}
}
}
输出:
sudo java Main
[sudo] password for jaysmito:
192.168.0.1 is reachable
192.168.0.2 is reachable
192.168.0.3 is reachable
192.168.0.4 is reachable
192.168.0.10 is reachable
Scan Completed taking 250151 miliseconds approximately!
import java.net.*;
import java.io.*;
import java.util.*;
class AddressFinderLevel4 extends Thread{
private String addmask;
private Stack<String> stack;
private int start, end;
public AddressFinderLevel4(String addmask, Stack stack, int start, int end){
this.addmask = addmask;
this.stack = stack;
this.start = start;
this.end = end;
}
@Override
public void run(){
try{
int timeout=1000;
for(int i = start; i <= end; i++){
String host=addmask + "." + i;
if (InetAddress.getByName(host).isReachable(timeout)){
stack.push(host);
}
}
}catch(Exception ex){
}
}
}
class AddressFinderLevel3 extends Thread{
private String addmask;
private Stack<String> stack;
private int start, end;
private int packSize;
public AddressFinderLevel3(String addmask, Stack stack, int packSize, int start, int end){
this.addmask = addmask;
this.stack = stack;
this.start = start;
this.end = end;
this.packSize = packSize;
}
@Override
public void run(){
try{
for(int i = start; i <= end; i++){
int j = 1;
String host = addmask + "." + i;
while(j<=255){
AddressFinderLevel4 addressFinderLevel4 = new AddressFinderLevel4(host, stack, j, j+packSize+5);
addressFinderLevel4.start();
j = j + packSize;
}
}
}catch(Exception ex){
ex.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) throws Exception {
System.out.println("Starting search!");
Stack data = find();
Thread.sleep(1000);
System.out.println("Data found in 1000 miliseconds");
data.forEach(System.out::println);
Thread.sleep(10000);
System.out.println("Data found in 10000 miliseconds");
data.forEach(System.out::println);
Thread.sleep(25000);
System.out.println("Data found in 25000 miliseconds");
data.forEach(System.out::println);
}
public static Stack find(){
Stack<String> stack = new Stack<String>();
AddressFinderLevel3 finder = new AddressFinderLevel3("192.168", stack, 10, 0, 255);
finder.start();
return stack;
}
}
sudo java Main
Starting search!
Data found in 1000 miliseconds
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
Data found in 10000 miliseconds
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.99.152
192.168.0.10
192.168.102.227
192.168.99.161
Data found in 25000 miliseconds
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.99.152
192.168.0.10
192.168.102.227
192.168.99.161
正如您所看到的,这个程序在更短的时间内扫描了更多的IP地址。
我也尝试对所有可能的IP地址进行扫描,但那需要太多的内存,也是不必要的!
这是一个更快的解决方案,因此应该表现更好!
如果您想要一个连接到网络的所有主机列表,我认为唯一保证可行的方法是遍历IP地址列表并对它们进行ping测试。
话虽如此,如果您正在寻找更具体的内容,可能有一些可以查找的内容(例如RMI的注册表(LocateRegistry.getRegistry(host, port).list()
))。
此外,如果您只想要给定主机拥有的所有IP地址,请查看NetworkInterface.getNetworkInterfaces()
。
显示局域网上的活动地址
public static void main(String[] args) {
try {
Enumeration nis = NetworkInterface.getNetworkInterfaces();
while(nis.hasMoreElements())
{
NetworkInterface ni = (NetworkInterface) nis.nextElement();
Enumeration ias = ni.getInetAddresses();
while (ias.hasMoreElements())
{
InetAddress ia = (InetAddress) ias.nextElement();
System.out.println(ia.getHostAddress());
}
}
} catch (SocketException ex) {
Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
输出
127.0.0.1
0:0:0:0:0:0:0:1
172.128.1.102
对我来说,这些都没有起作用,因为我已经创建了服务器,它没有响应这些ping。因此,我创建了一种机制,使服务器回复ping,并对子网中的所有地址使用暴力检查方法。
附注:写这篇文章是因为有人创建自己的服务器可能需要这个。