I'm writing a Java program that will show the names and IP addresses of the devices connected to my Wifi network.
I've figured out the IP address part. Here's the code :
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");
}
}
}
This code works and it shows the IP addresses of the connected devices.
But there are two problems that I'm facing:
So how do I display the name of the connected devices and is there any way to speed this program up?
Any help is appreciated!
Lowering the timeout value is one way to speed up the discovery process, but with Java 8 came parallel streams. With parallel streams you can discover remote network devices in parallel rather than sequential, and its the sequential process that eats up your time.
Here's how I would try using parallel streams to discover network devices.
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);
}
}
Results:
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
As you can see, using parallel streams make a pretty significant difference as far as processing time.
As far as the name being the IP address again, see InetAddress Documentation particularly
This program works really slow. It takes 254 seconds to complete.
I think I know why. From the InetAddress documentation :
public boolean isReachable(int timeout)
throws IOException
The timeout value, in milliseconds, indicates the maximum amount of time the try should take . If the operation times out before getting an answer, the host is deemed unreachable. A negative value will result in an IllegalArgumentException being thrown.
Therein lies your problem. If you allocate a second as your timeout
value, your program will take 254 seconds to complete if all hosts were unreachable. Try reducing it.
Hi Maybe it's too late to put an answer put I was searching on a solution for the same problem and maybe my answer would be useful for other I think that the scanners program use the multi threading for speed up the search and it's really effective that's my code
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();
}
}
}
maybe it's harmful to generate 253 thread but splitting them to multi threads like each 10 of them in one thread it will effectively speed up the process
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.