It's really easy. If you have some clue about network programming and Java, this shouldn't be extra hard to understand. It's about zero-configuration, the ability of devices to e.g. discover them independently of any server. There are several implementations, I choose to use Bonjour, which is provided and developed by Apple. The Java-Bindings are available for Windows and, of course, Mac.

To use them, you have to install.. nothing on a Mac ( I actually don't know when they introduced it to be a part of OS X, but anyone not using a 10 year old Mac should be fine ), and Bonjour for Windows for Windows. Install your JRE prior to running the Bonjour installer, as it won't install the Java Bindings if it doesn't find a working JRE.

Bonjour is one implementation of Zeroconf. It uses Multicast DNS in combination with DNS Service Discovery to allow for service browsing and discovery. Many Windows-Users may have wondered about the mDNSResponder.exe process running all the time. It's Bonjour.

So, let's pretend you're writing a killer-network-application that wants to notify other instances of it running in the network of its existence. It would have to call it out, which is done quite simply as follows.

First of all you have to do the import stuff, thats self-explaining i guess


now let's call the class thats responsible for announcing the service ServiceAnnouncer. The interface is as follows:

public interface IServiceAnnouncer {
	public void registerService();
	public void unregisterService();
	public boolean isRegistered();

It's quite simple and I intentionally didn't include any methods for setting the service' name etc. for simplicity. Now let's go over to the implementation part.

public class ServiceAnnouncer implements IServiceAnnouncer, RegisterListener {
	private DNSSDRegistration serviceRecord;
	private boolean registered;

	public boolean isRegistered(){
		return registered;

	public void registerService()  {
		try {
			serviceRecord = DNSSD.register(0,0,null,"_killerapp._tcp", null,null,1234,null,this);
		} catch (DNSSDException e) {
			// error handling here

	public void unregisterService(){
                registered = false;

	public void serviceRegistered(DNSSDRegistration registration, int flags,String serviceName, String regType, String domain){
		registered = true;

	public void operationFailed(DNSSDService registration, int error){
		// do error handling here if you want to.

The first thing you'll probably notice is the interface RegisterListener. It contains the callbacks operationFailed and serviceRegistered that are called by the Bonjour library if registering your service either fails or succeeds. Caused by the way Bonjour works this is required.

Let's have a look at the registerService method. As you can see, it consists basically of calling one static method from the DNSSD class. It's the method registerService. If you want to have a closer look just look at it's Javadoc. This method is the core of the whole service-register orgy, and it requires quite a few arguments, although using default values will work for you most of the times. What are these arguments? The method signature looks like this

public static DNSSDRegistration register(int flags,
                                         int ifIndex,
                                         java.lang.String serviceName,
                                         java.lang.String regType,
                                         java.lang.String domain,
                                         java.lang.String host,
                                         int port,
                                         TXTRecord txtRecord,
                                         RegisterListener listener)
                                  throws DNSSDException

Well, the first field is flags, the only flag that is valid there is NO_AUTO_RENAME, which will cause two services with the same name not being renamed automatically ( like "Killerapp 2" ). Passing 0 is fine if you don't want this behaviour. The next argument, interface index, is more interesting, as it allows you to specify on what interfaces to announce a service. Passing 0 will register your service an all available interfaces, -1 just for your local machine and other values for the specific device you want. 0 is mostly fine here, too.

Now it comes to the customisable part, serviceName is simply a string containing your applications name followed by some identifier, e.g. "Killerapp running on Killer Computer". If you pass null, Bonjour will simply use the computers name. Next is the regType field, should be something like "_killer._tcp". Important is the dot and the underscores. The protocol can, of course, be also udp if you want to.

Domain let's you choose the domain on which to announce the service, using null is fine here, as well as for the next argument, host. It just specifies the target host-name, but if you pass null, things will work. Next argument is the port on which your application accepts incoming connections.

Bonjour features the ability to have some "payload" associated with your service record, so that not only a name and port are announced, but there is also the possibility for another computer to get a so-called TXTRecord associated with your registered service. This can be quite useful, and if you want to use it, just read further through Apple's documentation.

The last argument is simply the listener, this is, our class. So passing this will be fine, as we implement the RegisterListener interface. You can use some other object here if you want to, but I think it's most clean to have it here.

The method returns a service handle of the type DNSSDRegistration, used in the unregisterService to cancel the service announcement.

That's it for the server part.The client part is explained here!