diff options
author | jestin | 2002-06-04 17:02:02 +0000 |
---|---|---|
committer | jestin | 2002-06-04 17:02:02 +0000 |
commit | 6a0be62488b406149903a7368cea8df0f1f27d33 (patch) | |
tree | ec3073dae7e11b55b3badef001a39fcb5ec6a1e1 /src/IvyWatcher.java | |
parent | ba4e7756c028129dc0c22650b17ba52ee92c6056 (diff) | |
download | ivy-java-6a0be62488b406149903a7368cea8df0f1f27d33.zip ivy-java-6a0be62488b406149903a7368cea8df0f1f27d33.tar.gz ivy-java-6a0be62488b406149903a7368cea8df0f1f27d33.tar.bz2 ivy-java-6a0be62488b406149903a7368cea8df0f1f27d33.tar.xz |
Many major corrections, see changelogs for details.
- Domain bug fix
- die semantics OK
- non CPU-eating socket listeners
cVS: ----------------------------------------------------------------------
Diffstat (limited to 'src/IvyWatcher.java')
-rwxr-xr-x | src/IvyWatcher.java | 160 |
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); |