我正在编写一个Java程序,它将显示连接到我的Wifi网络的设备的名称和IP地址。
我已经找到了IP地址部分。这是代码:
public static void main(String[] args) throws IOException {
InetAddress localhost = InetAddress.getLocalHost();
// this code assumes IPv4 is used
byte[] ip = localhost.getAddress();
for (int i = 1; i <= 254; i++) {
ip[3] = (byte) i;
InetAddress address = InetAddress.getByAddress(ip);
if (address.isReachable(1000)) {
// machine is turned on and can be pinged
System.out.println(address + "is online");
} else if (!address.getHostAddress().equals(address.getHostName())) {
// machine is known in a DNS lookup
System.out.println(address + "is in a DNS lookup");
} else {
// the host address and host name are equal, meaning the host name could not be resolved
System.out.println(address + " is not online");
}
}
}
此代码有效,它显示已连接设备的IP地址。
但是我面临两个问题:
那么如何显示所连接设备的名称,有没有办法加速这个程序?
感谢任何帮助!
答案 0 :(得分:3)
降低超时值是加快发现过程的一种方法,但Java 8带来了并行流。使用并行流,您可以并行发现远程网络设备而不是顺序,以及耗费时间的顺序流程。
以下是我尝试使用并行流来发现网络设备的方法。
public static void main(String[] args) throws Exception {
byte[] localHostIp = InetAddress.getLocalHost().getAddress();
List<DiscoverNetworkDevice> networkDevices = new ArrayList();
for (int i = 1; i < 255; i++) {
// Assuming IPV4
localHostIp[3] = (byte) i;
networkDevices.add(new DiscoverNetworkDevice(
InetAddress.getByAddress(localHostIp).getHostAddress()));
}
discover(networkDevices);
parallelDiscover(networkDevices);
}
public static void discover(List<DiscoverNetworkDevice> networkDevices) {
long start = System.currentTimeMillis();
Object[] discoveredDevices = networkDevices
.stream()
.filter(nd -> nd.Discover()).toArray();
for (Object obj : discoveredDevices) {
System.out.println(obj);
}
long end = System.currentTimeMillis();
System.out.println("Elapsed: " + (end - start));
System.out.println();
}
public static void parallelDiscover(List<DiscoverNetworkDevice> networkDevices) {
long start = System.currentTimeMillis();
Object[] discoveredDevices = networkDevices
.parallelStream()
.filter(nd -> nd.Discover()).toArray();
for (Object obj : discoveredDevices) {
System.out.println(obj);
}
long end = System.currentTimeMillis();
System.out.println("Elapsed: " + (end - start));
System.out.println();
}
public static class DiscoverNetworkDevice {
private String hostIp;
private String hostName;
public DiscoverNetworkDevice(String hostIp) {
this.hostIp = hostIp;
}
public boolean Discover() {
try {
InetAddress host = InetAddress.getByName(hostIp);
if (host.isReachable(500)) {
hostName = host.getHostName();
return true;
}
} catch (IOException ioe) {
}
return false;
}
@Override
public String toString() {
return String.format("IP: %s \t Name: %s", hostIp, hostName);
}
}
结果:
IP: 192.168.1.1 Name: 192.168.1.1
IP: 192.168.1.121 Name: 192.168.1.121
IP: 192.168.1.137 Name: 192.168.1.137
Elapsed: 126523
IP: 192.168.1.1 Name: 192.168.1.1
IP: 192.168.1.121 Name: 192.168.1.121
IP: 192.168.1.137 Name: 192.168.1.137
Elapsed: 16113
正如您所看到的,就处理时间而言,使用并行流会产生非常显着的差异。
至于名称再次为IP地址,请参阅InetAddress Documentation特别是
答案 1 :(得分:2)
这个程序工作得很慢。完成需要254秒。
我想我知道为什么。来自InetAddress documentation:
public boolean isReachable(int timeout)
throws IOException
超时值(以毫秒为单位)表示尝试应采取的最长时间。如果在获得答案之前操作超时,则认为主机无法访问。负值将导致抛出IllegalArgumentException。
这就是你的问题所在。如果您分配一秒作为timeout
值,则如果所有主机都无法访问,则您的程序将需要254秒才能完成。尝试减少它。
答案 2 :(得分:0)
嗨,也许为时已晚,无法提出答案,我正在寻找同一问题的解决方案,也许我的回答对其他人有用 我认为扫描程序使用多线程来加速搜索 而且我的代码非常有效
public class NetLimiter {
public interface DiscoverDeviceEeventListener extends EventListener {
public void discovered(Device device);
public void failed(Device device);
}
DiscoverDeviceEeventListener discoverDeviceEventHandler = null;
public void setDiscoverDeviceEvent(DiscoverDeviceEeventListener handler) {
this.discoverDeviceEventHandler = handler;
}
public class Device {
private String hostIp;
private String hostName;
public Device(String hostIp) {
this.hostIp = hostIp;
EventListenerList l = new EventListenerList();
}
public boolean discover() {
try {
InetAddress host = InetAddress.getByName(hostIp);
if (host.isReachable(1000)) {
hostName = host.getHostName();
if (discoverDeviceEventHandler != null) {
discoverDeviceEventHandler.discovered(this);
}
return true;
} else if (discoverDeviceEventHandler != null) {
discoverDeviceEventHandler.failed(this);
}
} catch (IOException ioe) {
System.out.print(ioe);
}
return false;
}
@Override
public String toString() {
return String.format("IP: %s \t Name: %s", hostIp, hostName);
}
}
String subnet = "";
public NetLimiter(String subnet) {
this.subnet = subnet;
}
public void checkDevices() {
for (int i = 1; i < 255; i++) {
String host = subnet + "." + i;
(new Thread(){
@Override
public void run(){
(new Device(host)).discover();
}
}).start();
}
}
}
也许它对生成253线程有害,但是将它们分成多线程,就像在一个线程中每10个线程一样,它将有效地加速进程