aboutsummaryrefslogtreecommitdiff
path: root/src/IvyWatcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/IvyWatcher.java')
-rwxr-xr-xsrc/IvyWatcher.java160
1 files changed, 98 insertions, 62 deletions
diff --git a/src/IvyWatcher.java b/src/IvyWatcher.java
index 669287d..e371ea6 100755
--- a/src/IvyWatcher.java
+++ b/src/IvyWatcher.java
@@ -6,6 +6,7 @@ import java.io.*;
import java.util.StringTokenizer;
import gnu.regexp.*;
import java.util.Vector;
+import java.util.Enumeration;
/**
* A private Class for the Ivy rendezvous
@@ -14,18 +15,28 @@ import java.util.Vector;
* @author Yannick Jestin
* @author <a href="http://www.tls.cena.fr/products/ivy/">http://www.tls.cena.fr/products/ivy/</a>
*
- * right now, the rendez vous is on a UDP socket. The watcher will answer to
+ * right now, the rendez vous is either an UDP socket or a TCP multicast.
+ * The watcher will answer to
* each peer advertising its arrival on the bus. The intrinsics of Unix are so
* that the broadcast is done using the same socket, which is not a good
* thing.
+ *
+ * CHANGELOG:
+ * 1.0.10:
+ * - isInDomain() is wrong in multicast. I've removed it
+ * - there was a remanence effect in the datagrampacket buffer. I clean it up after each message
+ * - cleaned up the getDomain() and getPort() code
+ * - close message sends an interruption on all threads for a clean exit
+ * - removed the timeout bug eating all the CPU resources
+ * - now handles a Vector of broadcast listeners
*/
class IvyWatcher implements Runnable {
private static boolean debug = (System.getProperty("IVY_DEBUG")!=null);
- private Vector domainaddrList;
+ //private Vector domainaddrList;
private boolean watcherrunning = false;
private boolean isMulticastAddress = false;
- private Thread broadcastListener ;
+ private Vector broadcastListener ;
private Ivy bus; /* master bus controler */
private DatagramSocket broadcast; /* supervision socket */
// it can also be a MulticastSocket, which inherits from the previous
@@ -35,7 +46,7 @@ class IvyWatcher implements Runnable {
*/
IvyWatcher(Ivy bus) throws IvyException {
this.bus = bus;
- domainaddrList = new Vector();
+ //domainaddrList = new Vector();
}
/**
@@ -54,11 +65,14 @@ class IvyWatcher implements Runnable {
while( watcherrunning && bus.ivyRunning ) try {
broadcast.receive(packet);
String msg = new String(packet.getData()) ;
+ // clean up the buffer after each message
+ for (int i=0;i<buf.length;i++) { buf[i]=0; }
InetAddress remotehost = packet.getAddress();
traceDebug("BUSWATCHER Receive Broadcast from "+
remotehost.getHostName()+":"+packet.getPort());
- // check if remoteaddr is in our broadcast domain list otherwise we ignore the broadcast
- if ( !isInDomain( remotehost ) ) continue;
+ // we used to check if remoteaddr is in our broadcast domain list otherwise we
+ // ignore the broadcast
+ // if ( !isInDomain( remotehost ) ) continue;
StringTokenizer st = new StringTokenizer(msg);
if ( !st.hasMoreTokens()) {
System.err.println("Bad format "+msg);
@@ -89,36 +103,33 @@ class IvyWatcher implements Runnable {
}
} catch (java.io.InterruptedIOException jii ){
if (!watcherrunning) break;
+ System.out.println("DEBUG IvyClient: I have been interrupted");
} catch (java.io.IOException ioe ){
System.err.println("IvyWatcher IOException "+ ioe.getMessage() );
}
- broadcast.close();
- traceDebug("broadcast listener normal shutdown");
+ stop();
} // while
/**
* stops the thread waiting on the broadcast socket
*/
- void stop() { watcherrunning=false; }
-
- private void sendBroadcast(String data, String net) throws IvyException {
- try {
- // simple trick to expand to 255 (Alex Bustico)
- net += ".255.255.255";
- RE exp = new RE( "^(\\d+\\.\\d+\\.\\d+\\.\\d+).*");
- net = exp.substitute( net , "$1" );
- } catch ( REException e ){
- throw new IvyException("Bad broascat addr");
+ void stop() {
+ traceDebug("broadcast listener normal shutdown");
+ watcherrunning=false;
+ for (Enumeration e = broadcastListener.elements();e.hasMoreElements();) {
+ Thread t = (Thread) e.nextElement();
+ t.interrupt();
}
+ }
+
+ private static void sendBroadcast(String data, String domain, int port) throws IvyException {
+ MulticastSocket send ;
try {
- InetAddress iaddr = InetAddress.getByName(net);
- domainaddrList.addElement(iaddr);
- DatagramPacket packet = new DatagramPacket(
- data.getBytes(),
- data.length(),
- iaddr,
- broadcast.getLocalPort() );
- broadcast.send(packet);
+ InetAddress group = InetAddress.getByName(domain);
+ send = new MulticastSocket(port);
+ if (group.isMulticastAddress()) { ((MulticastSocket)send).joinGroup(group); }
+ DatagramPacket packet = new DatagramPacket( data.getBytes(), data.length(), group, port );
+ send.send(packet);
} catch ( UnknownHostException e ) {
throw new IvyException("Broadcast sent on unknown network "+
e.getMessage());
@@ -127,46 +138,47 @@ class IvyWatcher implements Runnable {
}
}
- void start(String domain) throws IvyException {
- String domainaddr;
- // parse Domain to get port number
- int port;
- int sep_index = domain.lastIndexOf( ":" );
- if ( sep_index == -1 ) {
- port = bus.DEFAULT_PORT;
- domainaddr = domain;
- } else {
- port = Integer.parseInt( domain.substring( sep_index +1 ));
- domainaddr = domain.substring(0,sep_index);
- }
- // Handling of multicast address
- try {
- InetAddress group = InetAddress.getByName(domainaddr);
- if (group.isMulticastAddress()) {
- isMulticastAddress = true;
- broadcast = new MulticastSocket(port ); // create the UDP socket
- ((MulticastSocket)broadcast).joinGroup(group);
- } else {
- broadcast = new MulticastSocket(port ); // create the UDP socket
+ void start(String net) throws IvyException {
+ String hello = bus.PROCOCOLVERSION + " " + bus.applicationPort + "\n";
+ StringTokenizer st = new StringTokenizer(net,",");
+ broadcastListener = new Vector();
+ while ( st.hasMoreTokens()) {
+ String s = st.nextToken() ;
+ String domainaddr=getDomain(s);
+ int port=getPort(s);
+ // System.out.println("Domaine: "+domainaddr+" : "+port);
+ try {
+ InetAddress group = InetAddress.getByName(domainaddr);
+ broadcast = new MulticastSocket(port);
+ // Handling of multicast address
+ if (group.isMulticastAddress()) {
+ isMulticastAddress = true;
+ ((MulticastSocket)broadcast).joinGroup(group);
+ }
+ } catch ( IOException e ) {
+ throw new IvyException("IvyWatcher I/O error" + e );
+ }
+ /*
+ try {
+ broadcast.setSoTimeout(100);
+ } catch ( java.net.SocketException jns ) {
+ throw new IvyException("IvyWatcher setSoTimeout error" + jns.getMessage() );
}
- } catch ( IOException e ) {
- throw new IvyException("IvyWatcher I/O error" + e );
- }
- try {
- broadcast.setSoTimeout(100);
- } catch ( java.net.SocketException jns ) {
- throw new IvyException("IvyWatcher setSoTimeout error" + jns.getMessage() );
+ */
+ // starts a Thread listening on the socket
+ watcherrunning=true;
+ Thread t = new Thread(this);
+ broadcastListener.addElement(t);
+ t.start();
+ // notifies our arrival on each domain: protocol version + port
+ sendBroadcast(hello,domainaddr,port);
}
- // starts a Thread listening on the socket
- watcherrunning=true;
- broadcastListener = new Thread(this);
- broadcastListener.start();
- // notifies our arrival on each domain: protocol version + port
- String hello = bus.PROCOCOLVERSION + " " + bus.applicationPort + "\n";
- StringTokenizer st = new StringTokenizer(domainaddr," \t:,");
- while ( st.hasMoreTokens()) { sendBroadcast( hello, st.nextToken() ); }
}
+ /*
+ * TODO
+ * deprecated since we use Multicast. How to check when we are in UDP
+ * broadcast ?
private boolean isInDomain( InetAddress host ){
byte rem_addr[] = host.getAddress();
for ( int i = 0 ; i < domainaddrList.size(); i++ ) {
@@ -182,6 +194,30 @@ class IvyWatcher implements Runnable {
traceDebug( "host " + host + " Not in domain\n" );
return false;
}
+ */
+
+ private static String getDomain(String net) {
+ int sep_index = net.lastIndexOf( ":" );
+ if ( sep_index != -1 ) { net = net.substring(0,sep_index); }
+ try {
+ net += ".255.255.255";
+ RE exp = new RE( "^(\\d+\\.\\d+\\.\\d+\\.\\d+).*");
+ net = exp.substitute( net , "$1" );
+ } catch ( REException e ){
+ System.out.println("Bad broascat addr " + net);
+ return null;
+ }
+ //System.out.println("net: "+net);
+ return net;
+ }
+
+ private static int getPort(String net) {
+ int sep_index = net.lastIndexOf( ":" );
+ int port= ( sep_index == -1 ) ? Ivy.DEFAULT_PORT :Integer.parseInt( net.substring( sep_index +1 ));
+ // System.out.println("net: ["+net+"]\nsep_index: "+sep_index+"\nport: "+port);
+ return port;
+ }
+
private void traceDebug(String s){
if (debug) System.out.println("-->ivywatcher<-- "+s);