Are There Any Other Java Libraries for Bonjour/Zeroconf Apart from Jmdns

How to do something like Bonjour using open source library?

I think you definitely should take a look at UPnP. Considering the cross-platformness of such a solution, and its implementation using Java, you can consider

  • UPNPLib
  • Cyberlynk for Java
  • And even the various ways to connect an OSGi application to UPnP.

Finally, considering existing implementation of Bonjour using Java, this reply to a stackoverflow question sums it up.

DNS-SD: Experience with mdnsjava?

Meanwhile I can say, that mdnsjava is working very very good and stable in most situations. Much better & faster compared to jMDNS.

Here's some code to restart the full discovery and to start/stop the discovery, maybe it helps someone:

MulticastDNSService mDNSService = null;
Browse browse = null;
Object serviceDiscoveryInstance = null;

public void stop() {
try {
if (serviceDiscoveryInstance != null && mDNSService != null) {
mDNSService.stopServiceDiscovery(serviceDiscoveryInstance);
mDNSService.close();
}

serviceDiscoveryInstance = null;
//mDNSService = null;
if (browse != null) {
browse.close();
// this is required, otherwise the listeners won't get called in next run
browse = null;
}

Querier querier = MulticastDNSLookupBase.getDefaultQuerier();
if (querier != null) {
querier.close();
}
MulticastDNSLookupBase.setDefaultQuerier(null);
} catch (Exception e) {
Log(..)
}
}

public void start() {
try {
Querier querier = MulticastDNSLookupBase.getDefaultQuerier();
if (querier != null) {
if (mDNSService == null) {
mDNSService = new MulticastDNSService();
}

if (browse == null) {
browse = new Browse(SERVICE_TYPE);
}

if (serviceDiscoveryInstance == null) {
serviceDiscoveryInstance = mDNSService.startServiceDiscovery(browse, this);
}

// add existing entries
Lookup resolve = new Lookup(SERVICE_TYPE);
resolve.setQuerier(mDNSService.getQuerier());
ServiceInstance[] services = resolve.lookupServices();
for (ServiceInstance service : services) {
addDevice(service);
}
resolve.close();
} else {
Log.e("Cannot start mDNS-discovery because querier is not set up!");
resetDiscovery();
}
} catch (Exception e) {
Log.e("Error while discovering network.", e);
resetDiscovery();
}
}

public void clearCaches() {
if (MulticastDNSCache.DEFAULT_MDNS_CACHE != null) {
MulticastDNSCache.DEFAULT_MDNS_CACHE.clearCache();
}
mDNSService = null;
browse = null;
}

private void resetDiscovery(){
stop();
mDNSService = null;
browse = null;
}

You can start/stop the discovery with the mentioned methods, and reset the whole discovery via

stop();
clearCaches();
start();

mDNS code bonjour

A quick google search reveals:

  • http://code.google.com/p/mahalo-mdns/
  • http://jmdns.sourceforge.net/

How can I discover zeroconf (Bonjour) services on Android? I'm having trouble with jmDNS

I'm new as well otherwise I would have just left a comment on smountcastle's answer which is mostly correct. I have just been dealing with the exact same issue on a Droid running Android 2.1. I found that I needed to set the MulticastLock to reference-counted otherwise it seemed to be released automatically.

AndroidManifest.xml:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

// Networking code:
WifiManager wifi = getSystemService( Context.WIFI_SERVICE );
MulticastLock lock = wifi.createMulticastLock("fliing_lock");
lock.setReferenceCounted(true);
lock.acquire();

Just make sure to call lock.release() when you're done with it. This may only be necessary for Android 2.0+, The Droid is my only test device currently, so I can't say for sure.

Multiple sockets required for Zeroconf/bonjour implementation?

To quote the rfc:

When this document uses the term "Multicast DNS", it should be taken
to mean: "Clients performing DNS-like queries for DNS-like resource
records by sending DNS-like UDP query and response packets over IP
Multicast to UDP port 5353."

To fully implement mDNS (Bonjour), you need an open socket bound to 224.0.0.251 (the reserved IPv4 address) and port 5353 open to receive queries.

Obviously this just covers the Zeroconf implementation- whatever service you're advertising will require more ports & sockets open.

Is there a working network service discovery example with mdnsjava?

Turns out the easiest answer was to roll my own with MulticastSocket, at least for my simple application.

Note to anyone trying to do this: it wasn't much fun trying to make the client work in .NET CF 3.5. There is no asynchronous support, timeouts don't work, and the documentation on multicast support (in CF) is nonexistent. I ended up writing a synchronous client in its own thread. It returns the first couple of servers immediately, and then waits for others for over a minute. Brutal.

import java.net.MulticastSocket;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Main {
public static void main(String[] args) {
if( args.length == 0 ) runClient();
if(args[0].equals("s")) runServer();
else runClient();
}

static String mcastAddr = "239.255.100.100"; // Chosen at random from local network block at http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
static int port = 4446;

public static void runServer() {
while (true) {
try {
MulticastSocket s = new MulticastSocket(port);
InetAddress group = InetAddress.getByName(mcastAddr);
s.joinGroup(group);

byte[] recData = new byte[100];
DatagramPacket receivePacket = new DatagramPacket(recData, recData.length);
s.receive(receivePacket);
String strrec = new String(recData,0,receivePacket.getLength());
print("server received: " + strrec);
print("from: " + receivePacket.getAddress().toString());

if(strrec.equals("Are you there?")) {
String msg = "Here I am";
byte[] msgData = msg.getBytes();
DatagramPacket msgPacket = new DatagramPacket(msgData, msgData.length, receivePacket.getAddress(), receivePacket.getPort());
s.send(msgPacket);
print("server sent: " + msg + "\n");
} else {
print("Didn't send; unrecognized message.");
}

} catch (Exception e) {
print(e.toString());
}
}
}

public static void runClient() {
try {
DatagramSocket s = new DatagramSocket();

String msg = "Are you there?"; // Magic string
byte[] msgData = msg.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(msgData, msgData.length, InetAddress.getByName(mcastAddr), port);
s.send(datagramPacket);
print("client sent: " + msg);

byte[] recData = new byte[100];
DatagramPacket receivePacket = new DatagramPacket(recData, recData.length);
s.receive(receivePacket);
String strrec = new String(recData,0,receivePacket.getLength());
print("client received: " + strrec);
print("from " + receivePacket.getAddress().toString() + " : " + receivePacket.getPort());

System.exit(0);
} catch (Exception e) {
print(e.toString());
}
}
static void print(String s) { System.out.println(s); }
}


Related Topics



Leave a reply



Submit