Suppose I'm running several servers serving basic requests on my local network (say a home network, where all machines generally have an IP in the form K.K.K.x, where x is variable). Is there an easy way to discover all such servers? I would need to find each IP on the network running a particular java server application.
So you have a class C network... just attempt to open the particular server applications port on each IP address between 1 and 254. If you want to get fancy, you can do some checks to verify that if the port actually opens, it does what you expect for that application.
Since not every webserver listens on a fixed port of 80
, you'll need to scan ports. Open (and close!) in a loop a socket on every port, you can use java.net.Socket
for this. If success, then fire a simple GET request on /
on the IP/port in question, you can use java.net.URLConnection
for this. If you receive a valid HTTP response (regardless of the status code), then it's a webserver. You can determine the server type by the Server
header in the HTTP response. You however need to take into account that the default response header can be spoofed/removed/changed by the server admin.
Note that some firewalls may recognize the scanning pattern of a port scanner and block this.
I would scan IP range and test Socket connection to port 80 with a code like this:
try {
s = new Socket(addr,80);
System.out.println("Webserver found on IP:" + addr );
s.close();
}
catch (IOException ex) {
System.out.println("Webserver NOT found on IP:" + addr );
}
Are you looking for a solution within your Java application? If you are simply looking for a one-time solution, nmap should work.
If your local network is of the form 192.*.*.* try this (I added sudo because it must be run as root):
sudo nmap -vv -sS -O -n "192.168.1.1/24"
There are 2 basic ways to achieve this, and both require you to send/receive packets to/from each host you want to check.
The simplest approach is trying to establish the TCP connection to the desired port, as you'd normally do.
A more complicated and fancy approach, but faster in terms of execution, is sending a SYN packet, and waiting for a response packet. If the response is a SYN/ACK, it means the port is open (waiting for a connection), otherwise, it isn't. However, Java doesn't provide the necessary API (see raw socket) for this. You'd have to find a library/wrapper or write one using C and JNI.
For more insights to the 2nd option, read this.