001    /*
002     * $Id: SocketChannel.java,v 1.6 2004/02/04 22:41:21 kredel Exp $
003     */
004    
005    //package edu.unima.ky.parallel;
006    package comm;
007    
008    import java.io.*;
009    import java.net.*;
010    
011    /**
012     * SocketChannel.
013     * This class provides a communication channel using TCP/IP sockets. 
014     * @author Akitoshi Yoshida
015     * @author Heinz Kredel.
016     */
017    public class SocketChannel {
018      /*
019       * input stream from the socket
020       */
021      private ObjectInputStream in;
022    
023      /*
024       * output stream to the socket
025       */
026      private ObjectOutputStream out;
027    
028      /*
029       * socket
030       */
031      private Socket soc;
032    
033      /**
034       * Constructs a socket channel on the given socket s.
035       * @param s A socket object.
036       */
037      public SocketChannel(Socket s) throws IOException {
038        soc = s;
039        if (checkOrder(s)) {
040          in = new ObjectInputStream(s.getInputStream());
041          out = new ObjectOutputStream(s.getOutputStream());
042        }
043        else {
044          out = new ObjectOutputStream(s.getOutputStream());
045          in = new ObjectInputStream(s.getInputStream());
046        }
047      }
048    
049      /**
050       * Get the Socket.
051       */
052      public Socket getSocket() {
053          return soc;
054      }
055    
056      /**
057       * Sends an object.
058       */
059      public void send(Object v) throws IOException {
060        synchronized (out) {
061          out.writeObject(v);
062        }
063      }
064    
065      /**
066       * Receives an object.
067       */
068      public Object receive() throws IOException, ClassNotFoundException {
069        Object v = null;
070        synchronized (in) {
071          v = in.readObject();
072        }
073        return v;
074      }
075    
076      /**
077       * Closes the channel.
078       */
079      public void close() {
080        if (in != null) {
081          try { in.close(); } catch (IOException e) { }
082        }
083        if (out != null) {
084          try { out.close(); } catch (IOException e) { }
085        }
086        if (soc != null) {
087          try { soc.close(); } catch (IOException e) { }
088        }
089      }
090    
091      /**
092       * to string.
093       */
094      public String toString() {
095          return "socketChannel(" + soc + ")"; //" |@in " +in.available()+
096      }
097    
098      /*
099       * Determines the order of stream initialization.
100       * @param s A socket's object.  
101       */
102      private boolean checkOrder(Socket s) throws IOException {
103        // first use the port numbers as the key
104        int p1 = s.getLocalPort();
105        int p2 = s.getPort();
106        if (p1 < p2) return true;
107        else if (p1 > p2) return false;
108    
109        // second use the inetaddr as the key
110        int a1 = s.getLocalAddress().hashCode();
111        int a2 = s.getInetAddress().hashCode();
112        if (a1 < a2) return true;
113        else if (a1 > a2) return false;
114    
115        // this shouldn't happen
116        throw new IOException();
117      }
118    }