tags:

views:

181

answers:

5

A while ago I developed a little LAN chat app. in Java which allows chatting with other hosts, send images, etc. Although it was created just for fun, now it's being used where I work.

Currently, there is no "chat server" on the app. where each client registers, updates it's status, etc. (I liked the idea of symmetric design and not depending on a server running on some other machine).

Instead, each host is a client/server which has a hosts.properties file with the hostname of the other hosts, and - for instance - broadcasts to each one of them when sending a massive message/image/whatever.

In the beginning there were just a couple of hosts, so this hosts.properties file wasn't an issue. But as the amount of users increased, the need of updating that file was a bit daunting. So now I've decided to get rid of it, and each time the app. starts, dynammically find the other active hosts.

However, I cannot find the correct way of implement this. I've tried starting different threads, each one of them searching for other hosts in a known range of IP addresses. Something like this (simplified for the sake of readability):

/** HostsLocator */
public static void searchForHosts(boolean waitToEnd) {
    for (int i=0; i < MAX_IP; i+= MAX_IP / threads) {
        HostsLocator detector = new HostsLocator(i, i+(MAX_IP / threads - 1)); // range: from - to
        new Thread(detector).start();                 
    }
}

public void run() {
    for (int i=from; i<=to; i++)
        findHosts( maskAddress + Integer.toString(i) );
}

public static boolean findHosts(String IP) {
    InetAddress address = InetAddress.getByName(IP);
    if ( address.isReachable(CONNECTION_TIME_OUT) )
        // host found!
}

However:

  • With a single thread and a low value in CONNECTION_TIME_OUT (500ms) I get wrong Host Not Found status for for hosts actually active.
  • With a high value in CONNECTION_TIME_OUT (5000ms) and only one single thread takes forever to end
  • With several threads I've also found problems similar like the first one, due to collisions.

So... I guess there's a better way of solving this problem but I couldn't find it. Any advice? Thanks!

A: 

Each host keeps track of all the hosts they have met. When you shut down, save the known hosts to file and reuse the next time you start up.

Every so many minutes, send each of the known hosts a list of all known hosts.

That way

a) No network scanning
b) A new host will spread around the network

Then when a new host joins, he just needs to know 1 other host to learn about everyone.

A host that isn't seen for a week, or is seen from a new IP is dropped from the list of updated.

bwawok
+1  A: 

You could do this a lot easier using UDP. Check this tutorial for examples.

krock
A: 

You could attempt to use DNS service discovery

There seems to be a project on sourceforge (that I have not looked at, beyond doing a cursory search...)

Steven Schlansker
+3  A: 

You could try UDP Broadcast to a specific port. All running instances of your app on the network could listen to that port and then respond with a message identifying them as a host.

filip-fku
+1 - This is roughly analogous to how the ARP protocol works.
Stephen C
A: 

Use Bonjour/Zeroconf.

The jmdns project has all you need.

Thorbjørn Ravn Andersen