43

How do I get list of IP addresses for devices connected to my same subnet using Java?

Celeo
  • 5,583
  • 8
  • 39
  • 41
jmj
  • 237,923
  • 42
  • 401
  • 438
  • 3
    What exactly do you mean by "IPs connected in LAN"? – Pekka Jul 27 '10 at 16:43
  • all the posts you have given are little bit time consuming and takes 8 minutes to search 50 PCS connected to the Lan, i want the fastest way to get Ip addresses connected to the Lan so that i can display it on the JCOMBOBOX please anybody gives me the fastest way, – Nilesh410451 May 20 '11 at 11:09

8 Answers8

54

this should work when the hosts on your network react to ICMP packages (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");
       }
   }
}

invoke the method for a subnet (192.168.0.1-254) like this:

checkHosts("192.168.0");

didnt test it but should work kinda like this. Obviously this only checks the 254 hosts in the last byte of the ip address...

check:

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/

hope that helped

fasseg
  • 17,504
  • 8
  • 62
  • 73
6

To list the hosts connected in a LAN you will need to ping all the available IP addresses on the subnet. But a ping message could be restricted by firewall thus safer way could be open a socket to each IP address in the LAN's IP address range.

Suhas Phartale
  • 777
  • 6
  • 3
3

Since Java 1.5 there is a ping-like method in java.net.InetAddress: public boolean isReachable(int timeout). You could use that to iterate over all the IP Addresses in your subnet... java-doc

vicatcu
  • 5,407
  • 7
  • 41
  • 65
1

If you mean a list of all hosts connected to the network, I think the only way that is guaranteed to work is to step through a list of IP addresses and ping them all.

That said, if you're looking for something more specific, there may be something you can look up (e.g. RMI's registry (LocateRegistry.getRegistry(host, port).list()).

Also, if you just want all the IP addresses that a given host has, have a look at NetworkInterface.getNetworkInterfaces().

Scott
  • 1,869
  • 3
  • 20
  • 25
  • 1
    Nope. LocateRegistry.getRegistry doesn't do any communications whatsoever. It just constructs a Registry stub. – user207421 Jul 28 '10 at 03:15
  • 1
    Calling list() on it should, though. Anyway, it's a bit moot - I'm forgetting that by default RMI only allows objects to register with local registries, so you'd still need to check for a registry on every host. You'd need to use something like Bonjour to do service discovery - which was my point. – Scott Jul 28 '10 at 11:34
1

I saw the other answer. Its pretty well. But its quite slow as compared to a real situation and should not be used in such a senario.

Here is what i am talking about.

When i use the answer https://stackoverflow.com/a/3345981/14911094

Code:

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");
       }
   }
}
}

The Output:

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!

This is pretty slow but i tried to make a better version using this concept:

Code:

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;
    }
}

The output:

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

As you can see this scans far more IPs in much much less time.

I had done it for all possible ips too but that takes too much memory and is not needed!

This is a faster solution thus should perform better!

Jaysmito Mukherjee
  • 1,467
  • 2
  • 10
  • 29
0

Shows Active Addresses On LAN

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);
    }
}

Output

127.0.0.1
0:0:0:0:0:0:0:1
172.128.1.102
Thusitha Wickramasinghe
  • 1,063
  • 2
  • 15
  • 30
-1

None of these were working for me as I had created the server and it didn't respond to these pings. So I created a mechanism that makes the server reply to a ping and used the brute force checking method for all addresses in the subnet.

PS: Writing this because someone creating their own server might need this.

Sumukha Pk
  • 124
  • 1
  • 7
-3

One of the problems here is that neither of the terms "LAN" and "connected" has a meaning in TCP/IP. The suggested technique of calling isReachable() on all the hosts in the class D subnet might work if your LAN corresponds precisely to a class-D subnet.

You might be better off looking at SAMBA, which can interrogate the LAN members via SMBs, so at least you'll be using a technique that has the same meaning for LAN that you do.

user207421
  • 305,947
  • 44
  • 307
  • 483