250 likes | 323 Views
Java API for distributed computing. Two pure Java mechanisms. Socket-based communication Endpoints of a two-way communication between two distributed components communicating with each other. Communication must be explicitly established by the two parties. Two pure Java mechanisms. RMI
E N D
Java API for distributed computing Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Two pure Java mechanisms • Socket-based communication • Endpoints of a two-way communication between two distributed components communicating with each other. • Communication must be explicitly established by the two parties Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Two pure Java mechanisms • RMI • Makes the network transparent • Allows distributed component manipulation almost as if they were on same host • Programmers do not deal with interhost communication Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Socket-based communication • Two kinds of sockets: • Server sockets: wait for requests from clients • Client sockets: used to send data to a server socket and receive data from it. • Server socket listens at a specific port. • This port completely distinguishes different servers running on the same host. • Server socket must be running on server host before any communicating client. • After contact by client • communication is established • Client socket is created for the app running on server host to communicate with client. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Server socket API • Constructors ServerSocket(int port) port: specifies port number at which server socket will be listening for clients When multiple client access server socket they will be placed in a queue. ServerSocket(int port, in backlog) backlog specifies max length of queue. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Common server socket methods Socket accept(); Waits for connection request Thread executing this call will be blocked until request is received, at which time returns a client socket. void close(); Stop waiting for requests from clients. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Typical code structure for server socket try{ ServerSocket server = new ServerSocket(port); for ( ; ; ){ Socket client = server.accept(); // handle client … } } catch(IOException exc) { // handle failure to create server socket } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Client socket • An instance of the Socket class. • Can be created one of two ways: • Using constructor: Socket( String host, int port); • On the server side, clients sockets returned by the accept method. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Socket communication • Communication between server and client handled by client sockets at both ends. • Each client socket has • an InputStream for receiving data • An OutputStream for sending data Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Common socket API InputStream getInputStream(); Returns an input stream for this socket. OutputStream getOutputStream(); Returns an output stream for this socket void close(); Closes this socket. Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Typical client socket code try{ Socket client = new Socket(host, port); PrintWriter out = new PrintWriter( new OutputStreamWriter(client.getOutputStream())); BufferedReader in = new BufferedReader( new InputStreamReader(client.getInputStream())); // send and receive data …. in.close(); out.close(); client.close(); } catch( IOException exc) { // handle failure of connection } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
import java.io.*; import java.net.*; class EchoServer { public static void main(String[] args) { System.out.println("EchoServer started."); try { ServerSocket server = new ServerSocket(8008); Socket incoming = server.accept(); System.out.println("Connected to: " + incoming.getInetAddress() + " at port: " + incoming.getLocalPort()); BufferedReader in = new BufferedReader(new InputStreamReader(incoming.getInputStream())); PrintWriter out = new PrintWriter(new OutputStreamWriter(incoming.getOutputStream())); out.println("Hello! This is Java EchoServer. "); out.println("Enter BYE to exit."); out.flush(); Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
// while (true) { String str = in.readLine(); if (str == null) { break; // client close } else { out.println("Echo: " + str); out.flush(); System.out.println("Received: " + str); if (str.trim().equals("BYE")) break; } }//end while incoming.close(); } catch (Exception e) { System.out.println("Error: " + e); } System.out.println("EchoServer stopped."); }//end main } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
To run a server • Enter the java command to execute it • To run a client • Enter the command to execute client followed by name of server host and port number where server is executing. • You can run for test purposes server and client on same host; client invocation will look: telnet localhost 8008 Or telnet 127.0.0.1 8008 Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
import java.io.*; import java.net.*; class EchoClient { public static void main(String[] args) { try { String host; if (args.length > 0 && args[0] != null) { host = args[0]; } else { host = "localhost"; } Socket client = new Socket(host, 8008); BufferedReader in = new BufferedReader( new InputStreamReader(client.getInputStream())); PrintWriter out = new PrintWriter( new OutputStreamWriter(client.getOutputStream())); Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
//sending data to server: for (int i = 1; i <= 10; i++) { System.out.println("Sending: line " + i); out.println("line " + i); out.flush(); } out.println("BYE"); out.flush(); //receiving data from server: for (;;) { String str = in.readLine(); if (str == null) { break; } else { System.out.println(str); } }//end for } catch (Exception e) { System.out.println("Error: " + e); } }//end main } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
A multi-echo server • Using threads we can create sessions to handle clients. • The session needs a reference to the client socket Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
import java.io.*; import java.net.*; public class ClientHandler extends Thread { protected Socket incoming; public ClientHandler(Socket incoming) { this.incoming = incoming; } public void run() { try { BufferedReader in = new BufferedReader( new InputStreamReader(incoming.getInputStream())); PrintWriter out = new PrintWriter( new OutputStreamWriter(incoming.getOutputStream())); out.println("Hello! This is Java MultiEchoServer."); out.println("Enter BYE to exit."); out.flush(); Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
for (;;) { String str = in.readLine(); if (str == null) { break; } else { out.println("Echo: " + str); out.flush(); System.out.println("Received: " + str); if (str.trim().equals("BYE")) break; } } //end for incoming.close(); } catch (Exception e) { System.out.println("Error: " + e); } }//end run } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
import java.net.*; public class MultiEchoServer { public static void main(String[] args) { System.out.println("MultiEchoServer started."); try { ServerSocket s = new ServerSocket(8009); for (;;) { Socket incoming = s.accept(); new ClientHandler(incoming).start(); } } catch (Exception e) { System.out.println("Error: " + e); } System.out.println("MultiEchoServer stopped."); } } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
Broadcast echo server Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
import java.util.*; import java.io.*; import java.net.*; class BroadcastClientHandler extends Thread { protected Socket incoming; protected int id; protected BufferedReader in; protected PrintWriter out; public BroadcastClientHandler(Socket incoming, int id) { this.incoming = incoming; this.id = id; try { if (incoming != null) { in = new BufferedReader(new InputStreamReader(incoming.getInputStream())); out = new PrintWriter(new OutputStreamWriter(incoming.getOutputStream())); } } catch (Exception e) { System.out.println("Error: " + e); } } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
public synchronized void putMessage(String msg) { if (out != null) { out.println(msg); out.flush(); } } public synchronized void broadcastClients(String str){ Enumeration enum = BroadcastEchoServer.activeThreads.elements(); while (enum.hasMoreElements()) { BroadcastClientHandler client = (BroadcastClientHandler) enum.nextElement(); if (client != this) { client.putMessage("Broadcast(" + id + "): " + str); } } } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
public void run() { System.out.println("Client handler " + id + " started."); if (in != null && out != null) { putMessage("Hello! This is Java BroadcastEchoServer. Enter BYE to exit."); try { for (;;) { String str = in.readLine(); if (str == null) { break; } else { // str is not null putMessage("Echo: " + str); System.out.println("Received (" + id + "): " + str); if (str.trim().equals("BYE")) { break; } else { broadcastClients(str); } } //end else of not null str }//end for incoming.close(); BroadcastEchoServer.activeThreads.removeElement(this); } catch (IOException e) {} } System.out.println("Client thread " + id + " stopped."); } // end run } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads
public class BroadcastEchoServer { static protected Vector activeThreads; public static void main(String[] args) { System.out.println("BroadcastEchoServer started."); activeThreads = new Vector(); int i = 1; try { ServerSocket s = new ServerSocket(8010); for (;;) { Socket incoming = s.accept(); System.out.println("Spawning client thread " + i); BroadcastClientHandler newThread = new BroadcastClientHandler(incoming, i); activeThreads.addElement(newThread); newThread.start(); i++; } } catch (Exception e) { System.out.println("Error: " + e); } System.out.println("BroadcastEchoServer stopped."); } } Distributed Software Engineering C:\unocourses\4350\slides\DefiningThreads