aboutsummaryrefslogtreecommitdiff
path: root/src/IvyWatcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/IvyWatcher.java')
-rwxr-xr-xsrc/IvyWatcher.java278
1 files changed, 144 insertions, 134 deletions
diff --git a/src/IvyWatcher.java b/src/IvyWatcher.java
index 21311e9..bae387a 100755
--- a/src/IvyWatcher.java
+++ b/src/IvyWatcher.java
@@ -1,8 +1,3 @@
-/*
-*
-* IvyWatcher : gestion des messages UDP pour annoncer les arrivées
-*
-*/
package fr.dgac.ivy ;
import java.lang.Thread;
@@ -11,156 +6,171 @@ import java.io.*;
import java.util.StringTokenizer;
import gnu.regexp.*;
import java.util.Vector;
-public class IvyWatcher extends Thread {
- Ivy bus; /* master bus controler */
- DatagramSocket broadcast; /* supervision socket */
- private Vector domainaddrList;
+
+/**
+ * A private Class for the Ivy rendezvous
+ *
+ * @author François-Régis Colin
+ * @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
+ * 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.
+ */
+
+class IvyWatcher implements Runnable {
private static boolean debug = (System.getProperty("IVY_DEBUG")!=null);
+ private Vector domainaddrList;
+ private boolean watcherrunning = false;
+ private Thread broadcastListener ;
+ private Ivy bus; /* master bus controler */
+ private DatagramSocket broadcast; /* supervision socket */
+
+ /**
+ * creates an Ivy watcher.
+ * @param bus the bus
+ */
+ IvyWatcher(Ivy bus) throws IvyException {
+ this.bus = bus;
+ domainaddrList = new Vector();
+ }
- public void close() {
+ /**
+ * the behaviour of the thread watching the UDP socket.
+ * this thread will stop either when the bus stops or when the
+ * watcherrunning will be set to false
+ */
+ public void run() {
+ traceDebug("IvyWatcher waiting for Broadcast");
+ while( watcherrunning && bus.ivyRunning ) try {
+ byte buf[] = new byte[256];
+ DatagramPacket packet=new DatagramPacket(buf, 256);
+ int port;
+ broadcast.receive(packet);
+ String msg = new String(packet.getData()) ;
+ 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;
+ StringTokenizer st = new StringTokenizer(msg);
+ if ( !st.hasMoreTokens()) {
+ System.err.println("Bad format "+msg);
+ continue;
+ }
+ int version = Integer.parseInt( st.nextToken() );
+ if ( version != bus.PROCOCOLVERSION ) {
+ System.err.println("Ignoring bad protocol version broadcast");
+ continue;
+ }
+ if ( ! st.hasMoreTokens()) {
+ System.err.println("Bad format "+msg);
+ continue;
+ }
+ port = Integer.parseInt( st.nextToken() );
+ if ( (bus.applicationPort == port) ) continue;
+ traceDebug("BUSWATCHER Broadcast de "
+ +packet.getAddress().getHostName()
+ +":"+packet.getPort()+" port "+port+" version "+version);
+ try {
+ Socket socket = new Socket( remotehost, port );
+ bus.addClient(socket,false);
+ } catch ( UnknownHostException e ) {
+ System.err.println("Unkonwn host "+remotehost + e.getMessage());
+ } catch ( IOException e) {
+ System.err.println("can't connect to "+remotehost+" port "+
+ port+e.getMessage());
+ }
+ } catch ( IOException e ) {
+ watcherrunning=false;
+ traceDebug("broadcast listener crashed " + e.getMessage());
+ }
broadcast.close();
+ traceDebug("broadcast listener normal shutdown");
}
- private void sendBroadcast( String data, String net ) throws IvyException
- {
- DatagramPacket packet;
- // transformation en forme de broadcast w.x.y.z en w.x.y.255
- try {
- // simple trick to expend to 255 thank's Alex
- 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");
- }
- // broadcast sur l'adresse iadr
+
+ /**
+ * stops the thread waiting on the broadcast socket
+ */
+ void stop() { watcherrunning=false; }
+
+ private void sendBroadcast(String data, String net) throws IvyException {
try {
- InetAddress iaddr = InetAddress.getByName(net);
- domainaddrList.addElement( iaddr );
- packet = new DatagramPacket(
+ // 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");
+ }
+ try {
+ InetAddress iaddr = InetAddress.getByName(net);
+ domainaddrList.addElement(iaddr);
+ DatagramPacket packet = new DatagramPacket(
data.getBytes(),
data.length(),
iaddr,
broadcast.getLocalPort() );
- broadcast.send( packet );
+ broadcast.send(packet);
} catch ( UnknownHostException e ) {
- throw new IvyException("Broadcast sur réseau inconnu " + e );
+ throw new IvyException("Broadcast sent on unknown network "+
+ e.getMessage());
} catch ( IOException e ) {
- throw new IvyException("broadcast send erreur " + e );
+ throw new IvyException("Broadcast error " + e.getMessage() );
}
}
- public void sendStart(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);
- }
- // create the UDP socket
- try {
+
+ 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);
+ }
+ // create the UDP socket
+ try {
broadcast = new MulticastSocket(port );
} catch ( IOException e ) {
throw new IvyException("IvyWatcher erreur I/O" + e );
}
- // start UDP receiver
- start();
- // send hello world on UDP sockets
- String hello = "3 "+bus.getApplicationPort()+"\n";
- StringTokenizer st = new StringTokenizer(domainaddr," \t:,");
- while ( st.hasMoreTokens()) {
- sendBroadcast( hello, st.nextToken() );
- }
- }
-
- IvyWatcher(Ivy bus) throws IvyException {
- this.bus = bus;
- domainaddrList = new Vector();
+ // 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() ); }
}
-
- public void run() {
- DatagramPacket packet;
- byte buf[] = new byte[256];
- int port;
- int version;
- /**/
- traceDebug("IvyWatcher waiting for Broadcast");
- while( bus.ivyRunning() )
- {
- try {
- /* receive antoher application port */
- packet = new DatagramPacket(buf, 256);
- broadcast.receive( packet );
- String msg = new String(packet.getData()) ;
- InetAddress remotehost = packet.getAddress();
- traceDebug("BUSWATCHER Receive Broadcast from:"+
- remotehost.getHostName()+
- ":"+packet.getPort()
- +"'"+msg+"'");
- // check if remoteaddr is in our broadcast domain list
- if ( !isInDomain( remotehost ) )
- continue;
- StringTokenizer st = new StringTokenizer(msg);
- if ( ! st.hasMoreTokens()) {
- System.err.println("Bad format "+msg);
- continue;
- }
- version = Integer.parseInt( st.nextToken() );
- if ( ! st.hasMoreTokens()) {
- System.err.println("Bad format "+msg);
- continue;
- }
- port = Integer.parseInt( st.nextToken() );
- // TODO: More checking here host port domain etc....
- if ( (bus.getApplicationPort() == port) )
- {
- continue;
- }
- traceDebug("BUSWATCHER Broadcast de "
- +packet.getAddress().getHostName()+":"+packet.getPort()+" port "+port);
- /* connect to the application */
- try {
- Socket socket = new Socket( remotehost, port );
- bus.addClient( socket );
- } catch ( UnknownHostException e ) {
- System.err.println("Unkonwn host "+remotehost);
- } catch ( IOException e) {
- System.err.println("can't connect to "+remotehost+" port "+port);
- }
-
- } catch ( IOException e ) {
- // TODO: comment distinger la fin normale de 'erreur
- /* fermeture de la socket arret normal */
- traceDebug("Error IvyWatcher exception: " + e.getMessage());
+
+ private boolean isInDomain( InetAddress host ){
+ byte rem_addr[] = host.getAddress();
+ for ( int i = 0 ; i < domainaddrList.size(); i++ ) {
+ byte addr[] = ((InetAddress)domainaddrList.elementAt(i)).getAddress();
+ int j ;
+ for ( j = 0 ; j < 4 ; j++ )
+ if ( (addr[j] != -1) && (addr[j] != rem_addr[j]) ) break;
+ if ( j == 4 ) {
+ traceDebug( "host " + host + " is in domain\n" );
+ return true;
+ }
}
- }// end while
+ traceDebug( "host " + host + " Not in domain\n" );
+ return false;
}
-
+
private void traceDebug(String s){
if (debug) System.out.println("-->ivywatcher<-- "+s);
}
- private boolean isInDomain( InetAddress host ){
- byte rem_addr[] = host.getAddress();
- for ( int i = 0 ; i < domainaddrList.size(); i++ )
- {
- byte addr[] = ((InetAddress)domainaddrList.elementAt(i)).getAddress();
- int j ;
- for ( j = 0 ; j < 4 ; j++ )
- if ( (addr[j] != -1) && (addr[j] != rem_addr[j]) ) break;
- if ( j == 4 )
- {
- traceDebug( "host " + host + " is in domain\n" );
- return true;
- }
- }
- traceDebug( "host " + host + " Not in domain\n" );
- return false;
- }
-}
+
+} // class IvyWatcher
+/* EOF */