From a5ca9fd3f54783b7f9371d69574660f29fe0d10f Mon Sep 17 00:00:00 2001 From: jestin Date: Fri, 11 Aug 2000 09:15:47 +0000 Subject: Probe is the java implementation of ivyprobe(1). It supports the same syntax. --- src/IvyWatcher.java | 278 +++++++++++++++++++++++++++------------------------- 1 file changed, 144 insertions(+), 134 deletions(-) (limited to 'src/IvyWatcher.java') 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 http://www.tls.cena.fr/products/ivy/ + * + * 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 */ -- cgit v1.1