package jadex.standalone.transport.tcpmtp; import jadex.standalone.transport.MessageEnvelope; import jadex.standalone.transport.codecs.CodecFactory; import jadex.standalone.transport.codecs.IEncoder; import jadex.standalone.transport.tcpmtp.TCPTransport.Cleaner; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; /** * TCP output connection for sending messages to a specific target address. */ class TCPOutputConnection { //-------- constants -------- /** 5 sec timeout. */ public static final int TIMEOUT = 5000; //-------- attributes -------- /** The client socket for sending data. */ protected Socket sock; /** The output stream. */ protected OutputStream sos; /** The codec factory. */ protected CodecFactory codecfac; /** The cleaner. */ protected Cleaner cleaner; /** The classloader. */ protected ClassLoader classloader; //-------- constructors -------- /** * Create a new tcp connection for sending data. * @param iaddr * @param iport * @param enc * @throws IOException */ public TCPOutputConnection(InetAddress iaddr, int iport, CodecFactory codecfac, Cleaner cleaner, ClassLoader classloader) throws IOException { // try // { // System.out.println("TCP Connection: "+iaddr+":"+iport); this.sock = new Socket(); sock.connect(new InetSocketAddress(iaddr, iport), TIMEOUT); // System.out.println("TCP Connection: "+iaddr+":"+iport+" established"); // } // catch(IOException e) // { // System.out.println("TCP Connection: "+iaddr+":"+iport+" failed"); //// e.printStackTrace(); // throw e; // } this.sos = new BufferedOutputStream(sock.getOutputStream()); this.codecfac = codecfac; this.cleaner = cleaner; this.classloader = classloader; //address = SMTransport.SERVICE_SCHEMA+iaddr.getHostAddress()+":"+iport; } //-------- methods -------- /** * Send a message. * @param msg The message. * (todo: relax synchronization by performing sends * on extra sender thread of transport) */ public synchronized boolean send(MessageEnvelope msg) { boolean ret = false; try { IEncoder enc = codecfac.getDefaultEncoder(); byte codec_id = codecfac.getCodecId(enc.getClass()); if(codec_id==-1) throw new IOException("Codec id not found: "+enc); byte[] enc_msg = enc.encode(msg, classloader); int size = enc_msg.length+TCPTransport.PROLOG_SIZE; sos.write(codec_id); sos.write(size >> 24 & 0xFF); sos.write(size >> 16 & 0xFF); sos.write(size >> 8 & 0xFF); sos.write(size & 0xFF); sos.write(enc_msg); sos.flush(); ret = true; cleaner.refresh(); } catch(IOException e) { close(); } return ret; } /** * Test if the connection is closed. * @return True, if closed. */ public boolean isClosed() { return sock.isClosed(); } /** * Close the connection. */ public void close() { try { sock.close(); } catch(IOException e) { //e.printStackTrace(); } cleaner.remove(); } }