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