Networking infrastructure

The first assignment simplified the home networking situation in many ways


Events


Listeners


Listener list


Single listener

The source may have an implementation such as


      public class EventSource {
          Listener listener = null;

          public void setListener(Listener l) {
              if (l == null) {
                  listener = l;
              } else {
                  throw new java.util.TooManyListenersException();
              }
          }

          public void removeListener() {
              listener = null;
          }

          public void callListener(Event evt) {
              if (listener != null) {
                  listener.invoke(evt);
              }
          }
      }


Multiple listeners

The multiple listener source might be implemented by


public class EventSource {

    Vector listeners = new Vector();

    public void addListener(Listener l) {
        listeners.add(l);
    }

    public void removeListener(Listener l) {
        if ( ! listeners.remove(l)) {
            throw new NoSuchListenerException();
        }
    }

    public void callListeners(Event evt) {
        Enumeration enum = listeners.elements();

        while (enum.hasMoreElements()) {
            Listener listener = (Listener) enum.nextElement();
            listener.invoke(evt);
        }
    }
}


EventListenerList


EventHandler


Asynchronous event queue


EventQueue with one listener


public class EventQueue {
    protected Queue queue;
    protected Listener listener;

    public synchronised void addEvent(Event evt) {
        queue.add(evt);
        notifyAll();
    }

    public synchronised Event getEvent() {
        if (queue.isEmpty()) {
            wait();
        }
        return (Event) queue.removeElement():
    }

    public void dispatchEvents() {
        while (true) {
            Event evt = getEvent();
            if (listener != null) {
                listener.invoke(evt);
            }
        }
    }
}


Remote events


Procedure call


Remote procedure call


Example: World RPC


World pseudocode


WorldClient


public class WorldClient {

    public static void main(String[] args) {
	WorldStub w = new WorldStub();
	System.out.println(w.sayHello());
	System.out.println(w.sayGoodbye());
    }
}// WorldClient


WorldStub


import java.net.*;
import java.io.*;

public class WorldStub {

    private final String SERVER_IP = "127.0.0.1";
    private final int PORT = 7890;
    private static String SAY_HELLO = "sayHello";
    private static String SAY_GOODBYE = "sayGoodbye";

    private Socket s;
    private BufferedReader in;
    private PrintStream out;

    public WorldStub() {
	try {
	    InetAddress address = InetAddress.getByName(SERVER_IP);
	    s = new Socket(address, PORT);
	    in = new BufferedReader(new InputStreamReader(s.getInputStream()));
	    out = new PrintStream(s.getOutputStream());
	} catch(Exception e) {
	    System.err.println(e);
	    System.exit(1);
	}
    }

    public String sayHello() {
	try {
	    out.println(SAY_HELLO);
	    out.flush();
	    String response = in.readLine();
	    return response;
	} catch(IOException e) {
	    return "";
	}
    }

    public String sayGoodbye() {
	try {
	    out.println(SAY_GOODBYE);
	    out.flush();
	    String response = in.readLine();
	    return response;
	} catch(IOException e) {
	    return "";
	}
    }
}// WorldStub


WorldServer


import java.net.*;
import java.io.*;

public class WorldServer {

    private static int PORT = 7890;
    private static String SAY_HELLO = "sayHello";
    private static String SAY_GOODBYE = "sayGoodbye";

    public static void main(String[] args) {
	new WorldServer();
    }

    public WorldServer (){
	ServerSocket server = null;
	try {
	    server = new ServerSocket(PORT);
	} catch(IOException e) {
	    e.printStackTrace();
	    System.exit(1);
	}

	while (true) {
	    try {
		Socket client = server.accept();
		handleClient(client);
	    } catch(IOException e) {
		// ignore errors from a client
	    }
	}
    }
    
    private void handleClient(Socket client) {
	BufferedReader in = null;
	PrintStream out = null;
	String result = null;

	try {
	    in = new BufferedReader(new InputStreamReader(client.getInputStream()));
	    out = new PrintStream(client.getOutputStream());
	    String command = null;
	    while (true) {
		command = in.readLine();
		if (command.equals("")) {
		    break;
		}
		if (command.equals(SAY_HELLO)) {
		    result = sayHello();
		} else if (command.equals(SAY_GOODBYE)) {
		    result = sayGoodbye();
		}
		out.println(result);
	    }
	} catch(Exception e) {
	} finally {
	    try {
		if (in != null) {
		    in.close();
		}
		if (out != null) {
		    out.close();
		}
	    } catch(IOException e) {
		// nothing we can do
	    }
	}
    }

    private String sayHello() {
	System.err.println("hello");
	return "Hello world";
    }

    private String sayGoodbye() {
	System.err.println("bye");
	return "Goodbye cruel world";
    }
}// WorldServer


Comments on RPC


Half object plus protocol


Messaging systems


Message architectures


Mobile objects


Example migrating objects


IntegerClient


public class IntegerClient {

    public static void main(String[] args) {
	IntegerStub w = new IntegerStub();
    }
}// IntegerClient

IntegerStub


import java.net.*;
import java.io.*;

public class IntegerStub {

    private final String SERVER_IP = "127.0.0.1";
    private final int PORT = 7891;

    private Socket s;
    private ObjectInputStream in;

    public IntegerStub() {
	try {
	    InetAddress address = InetAddress.getByName(SERVER_IP);
	    s = new Socket(address, PORT);
	    in = new ObjectInputStream(s.getInputStream());
	    
	    for (int n = 0; n < 10; n++) {
		Integer nObj = (Integer) in.readObject();
		System.out.println(nObj.toString());
	    }
	} catch(Exception e) {
	    System.err.println(e);
	    System.exit(1);
	}
    }
}// IntegerStub


IntegerServer


import java.net.*;
import java.io.*;

public class IntegerServer {

    private static int PORT = 7891;

    public static void main(String[] args) {
	new IntegerServer();
    }

    public IntegerServer (){
	ServerSocket server = null;
	try {
	    server = new ServerSocket(PORT);
	} catch(IOException e) {
	    e.printStackTrace();
	    System.exit(1);
	}

	while (true) {
	    try {
		Socket client = server.accept();
		handleClient(client);
	    } catch(IOException e) {
		// ignore errors from a client
	    }
	}
    }
    
    private void handleClient(Socket client) {
	ObjectOutputStream out = null;

	try {
	    out = new ObjectOutputStream(client.getOutputStream());
	    for (int n = 0; n < 10; n++) {
		out.writeObject(new Integer(10-n));
	    }
	} catch(Exception e) {
	} finally {
	    try {
		if (out != null) {
		    out.close();
		}
	    } catch(IOException e) {
		// nothing we can do
	    }
	}
    }
}// IntegerServer


Dynamic class loading


Using interfaces for dynamic classes


Dynamic Foo loading


MarshalledObject


Conclusion

There are a variety if ways that one object can call methods on another, even if they are remote


Jan Newmarch <jan@newmarch.name>
Last modified: Sun Apr 21 23:46:08 EST 2002
Copyright © Jan Newmarch, Monash University, 2007
Creative Commons License This work is licensed under a Creative Commons License
The moral right of Jan Newmarch to be identified as the author of this page has been asserted.