package network.platform.ip; import network.platform.NetworkPlatformMessage; import model.interfaces.network.INetworkTraffic; import util.Parameters; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.InvalidClassException; import java.io.OptionalDataException; import java.io.StreamCorruptedException; import java.io.IOException; import java.net.ServerSocket; import java.net.SocketException; import java.net.Socket; import network.platform.PlatformMessagesReceptor; import util.NetworkAddress; import java.net.InetSocketAddress; import model.interfaces.network.INetworkServer; import platform.servicesregister.ServicesRegisterManager; import platform.servicesregister.ServiceClosedException; import platform.context.ContextManager; import platform.context.ContextInformation; import util.SizeCountOutputStream; import platform.plugins.installables.network.DNS.KalimuchoDNS; // classe du thread qui gere la reception des messages pour la PF /** * Thread that receive on IP messages for the PF and put them into a mailbox. * * @author Dalmau */ public class IPPlatformReceptionServer extends Thread implements INetworkServer, INetworkTraffic { private ServerSocket conn=null; // connexion par socket private Socket lien = null; private int numPort; // numero du port utilise par les PF private PlatformMessagesReceptor messagesRecus; // buffer de depot des messages de la PF private boolean enMarche; private ContextManager gestionnaireContexte; private int receivedData; private KalimuchoDNS dns; /** * Creates the thread that manages messages received for the PF. * @param adr address on which this server runs * @param b mailbox to put the messages * @param p port number for receiving these messages */ public IPPlatformReceptionServer(NetworkAddress adr, PlatformMessagesReceptor b, int p) { numPort = p; receivedData = 0; try{ conn = new ServerSocket(); // creation de la socket de service conn.bind(new InetSocketAddress(adr.getNormalizedAddress(), numPort)); } catch (IOException e) { System.err.println("Can't open IP connection for the platform on port "+numPort); } messagesRecus = b; gestionnaireContexte = (ContextManager)ServicesRegisterManager.platformWaitForService(Parameters.CONTEXT_MANAGER); setPriority(Thread.NORM_PRIORITY+2); start(); } /** * Server that receives the messages for the PF and puts them in the PF maibox. */ @Override public void run() { enMarche = true; while (enMarche) { NetworkPlatformMessage recu = null; try { if (conn != null) { // attente d'un message reseau pour la PF lien = conn.accept(); // recuperer le message // traitement d'un message pour la PF ObjectInputStream ois = new ObjectInputStream(lien.getInputStream()); recu = (NetworkPlatformMessage)ois.readObject(); // message recupere receivedData = receivedData+getMessageSize(recu); // mettre dans le message l'@ de l'expediteur recu.setAddress(recu.getExpeditorAddress()); // la condition suivante sert a simuler une non connectivite avec un hote if ((!lien.getInetAddress().getHostAddress().contains(Parameters.NETWORK_EXCLUSION))||(recu.getSenderID().equals("Deployment"))) { try { dns = (KalimuchoDNS)ServicesRegisterManager.lookForService(Parameters.KALIMUCHO_DNS_MANAGER); dns.addReference(recu.getSenderID(), lien.getInetAddress().getHostAddress(), true); if (!(new NetworkAddress(recu.getExpeditorAddress()).equals(new NetworkAddress(lien.getInetAddress().getHostAddress())))) dns.addReference(recu.getExpeditorID(), recu.getExpeditorAddress(), false); } catch (ServiceClosedException sce) { } messagesRecus.deposerMessage(recu); // le deposer dans le buffer pour la PF } lien.close(); ois.close(); } } catch (SecurityException se) { if (enMarche) gestionnaireContexte.signalEvent(new ContextInformation("Error when receiving PF message: security")); } catch (SocketException se) { if (enMarche) gestionnaireContexte.signalEvent(new ContextInformation("Error when receiving PF message: socket")); } catch (InvalidClassException ent) { if (enMarche) gestionnaireContexte.signalEvent(new ContextInformation("Error when receiving PF message: invalid class")); } catch (StreamCorruptedException ent) { if (enMarche) gestionnaireContexte.signalEvent(new ContextInformation("Error when receiving PF message: stream corrupted")); } catch (OptionalDataException ent) { if (enMarche) gestionnaireContexte.signalEvent(new ContextInformation("Error when receiving PF message: optional data")); } catch (ClassNotFoundException ent) { if (enMarche) gestionnaireContexte.signalEvent(new ContextInformation("Error when receiving PF message: class not found")); } catch (IOException ent) { if (enMarche) gestionnaireContexte.signalEvent(new ContextInformation("Error when receiving PF message: IO")); } } } /** * Stops the server that receive messages for the platform */ public void stopThread() { // Arret du serveur reseau qui recoit les messages pour la PF enMarche = false; try { conn.close(); } catch (IOException ioe) { System.err.println("Can't stop server for connectors' synchronisation"); } } /** * Returns the number of bytes received on network by the PF since the last call of this method. * @return the number of bytes received on network by the PF since the last call of this method. */ public int getDataSize() { int ret = receivedData; receivedData = 0; return ret; } private int getMessageSize(NetworkPlatformMessage s) { int taille; SizeCountOutputStream bos = new SizeCountOutputStream(); try { ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(s); taille = bos.getSize(); } catch (IOException ioe) { taille = 0; } return taille; } }