[英]Speed up finding devices connected to a Wifi network and get device name
我正在编写一个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地址。
但是我面临两个问题:
那么,如何显示所连接设备的名称,有什么方法可以加快此程序的速度?
任何帮助表示赞赏!
降低超时值是加快发现过程的一种方法,但是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文档
该程序的运行速度非常慢。 这需要254秒才能完成。
我想我知道为什么。 从InetAddress文档中 :
public boolean isReachable(int timeout)
throws IOException
超时值(以毫秒为单位)表示尝试应花费的最长时间 。 如果操作在获得答案之前超时,则认为主机不可访问。 负值将导致抛出IllegalArgumentException。
这就是你的问题。 如果您将秒数指定为timeout
值,则如果所有主机均无法访问,则程序将需要254秒才能完成。 尝试减少它。
嗨,也许现在把答案放在我正在寻找相同问题的解决方案的位置上为时已晚,也许我的答案将对其他人有用,我认为扫描仪程序使用多线程来加快搜索速度,这真的很有效码
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个线程,这将有效地加快进程
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.