/* * * IvyWatcher : gestion des messages UDP pour annoncer les arrivées * */ package fr.dgac.ivy ; import java.lang.Thread; import java.net.*; 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; private static boolean debug = (System.getProperty("IVY_DEBUG")!=null); public void close() { broadcast.close(); } 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 try { InetAddress iaddr = InetAddress.getByName(net); domainaddrList.addElement( iaddr ); packet = new DatagramPacket( data.getBytes(), data.length(), iaddr, broadcast.getLocalPort() ); broadcast.send( packet ); } catch ( UnknownHostException e ) { throw new IvyException("Broadcast sur réseau inconnu " + e ); } catch ( IOException e ) { throw new IvyException("broadcast send erreur " + e ); } } 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 { 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(); } 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()); } }// end while } 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; } }