package network.connectors.ip; import model.interfaces.network.INetworkTraffic; import network.connectors.DataAcquitmentManager; import network.connectors.DataAcquitmentSemaphore; import util.Parameters; import java.io.IOException; import java.io.InvalidClassException; import java.io.NotSerializableException; import network.connectors.EncapsulatedSample; import java.io.ObjectOutputStream; import platform.servicesregister.ServicesRegisterManager; import platform.servicesregister.ServiceClosedException; import java.net.Socket; import java.net.SocketException; import model.interfaces.network.IConnectorDataSender; import platform.context.ContextManager; import platform.context.ContextInformation; import util.SizeCountOutputStream; import network.AddressesChecker; import platform.plugins.installables.network.DNS.KalimuchoDNS; import util.NetworkAddress; /** * Sends data for on aconnector on IP * @author Dalmau */ public class IPConnectorDataSender implements IConnectorDataSender, INetworkTraffic { private DataAcquitmentManager listeAcquitements; private Socket env; private ObjectOutputStream ecrire; private String nom; private ContextManager gestionnaireContexte; private int sendedData; /** * Creates a data sender on IP for a connector * @param adresseIP address of the addressee (other part of this connector) on IP */ public IPConnectorDataSender(NetworkAddress adresseIP) { try { env = new Socket(adresseIP.getNormalizedAddress(), Parameters.PORT_IP_DATA_CONNECTORS); env.setTcpNoDelay(true); env.setKeepAlive(true); ecrire = new ObjectOutputStream(env.getOutputStream()); } catch (SocketException ie) { System.err.println("Can't put socket in TCP no delay mode"); } catch (IOException e) { System.err.println("Error creating IP connection for: "+nom); } sendedData = 0; gestionnaireContexte = (ContextManager)ServicesRegisterManager.platformWaitForService(Parameters.CONTEXT_MANAGER); listeAcquitements = (DataAcquitmentManager)ServicesRegisterManager.platformWaitForService(Parameters.CONNECTORS_ACKNOWLEDGE); } /** * Sends a message * @param connector connector sending the message * @param contenu sample sent */ public void sendMessage(String connector, EncapsulatedSample contenu) { nom = connector; DataAcquitmentSemaphore connexion = listeAcquitements.findConnexionDesignation(connector); connexion.NotAcquited(); int compteEssaiRestants = 3; while (compteEssaiRestants != 0) { try { // essayer d'etablir la connexion IP ecrire.reset(); // indispensable pour que java libere la memoire occupee par les caches du flux if (contenu != null) { // message normal // sendedData = sendedData+getSampleSize(contenu); sendedData = sendedData+contenu.size()+EncapsulatedSample.EXTRA_SIZE; ecrire.writeObject(contenu); compteEssaiRestants = 0; } else { // message de synchro AddressesChecker addressesChecker = (AddressesChecker)ServicesRegisterManager.platformWaitForService(Parameters.NETWORK_ADDRESSES); String myID = addressesChecker.getHostIdentifier(); ecrire.writeObject(connector+";"+myID); compteEssaiRestants = 0; } ecrire.flush(); } catch (InvalidClassException ice) { compteEssaiRestants = 0; gestionnaireContexte.signalEvent(new ContextInformation(nom+": error when sending data on IP: invalid class")); } catch (NotSerializableException ice) { compteEssaiRestants = 0; gestionnaireContexte.signalEvent(new ContextInformation(nom+": error when sending data on IP: not serializable class")); } catch (SocketException se) { try { KalimuchoDNS dns = (KalimuchoDNS)ServicesRegisterManager.lookForService(Parameters.KALIMUCHO_DNS_MANAGER); dns.removeReference(new NetworkAddress(env.getInetAddress().getHostAddress())); } catch (ServiceClosedException sce) { } compteEssaiRestants = 0; // Cette exception n'est pas une erreur elle se produit quand l'autre extremite du connecteur s'arrete } catch (IOException e) { compteEssaiRestants--; if (compteEssaiRestants == 0) { try { KalimuchoDNS dns = (KalimuchoDNS)ServicesRegisterManager.lookForService(Parameters.KALIMUCHO_DNS_MANAGER); dns.removeReference(new NetworkAddress(env.getInetAddress().getHostAddress())); } catch (ServiceClosedException sce) { } gestionnaireContexte.signalEvent(new ContextInformation(nom+": error when sending data on IP: IO")); } } } } /** * Stops the data sender on IP (closes the connexion) */ public void close() { try { ecrire.close(); env.close(); } catch (SocketException se) { // Cette exception n'est pas une erreur elle se produit quand l'autre extremite du connecteur s'arrete } catch (IOException e) { System.err.println("Error closing IP connection for: "+nom); } } /** * Returns the number of bytes sent on network by this connector's data sender since the last call of this method. * @return the number of bytes sent on network by this connector's data sender since the last call of this method. */ public int getDataSize() { int ret = sendedData; sendedData = 0; return ret; } private int getSampleSize(EncapsulatedSample 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; } }