650 likes | 755 Views
Lecture 8. Java Distributed Computing. Cheng-Chia Chen. Distributed Computing. Network programming JDBC Servlets & JSPs Remote Method Invocation (RMI) Others not covered: CORBA Enterprise JavaBeans (EJB) JINI JavaSpaces. Network programming.
E N D
Lecture 8. Java Distributed Computing Cheng-Chia Chen
Distributed Computing • Network programming • JDBC • Servlets & JSPs • Remote Method Invocation (RMI) • Others not covered: • CORBA • Enterprise JavaBeans (EJB) • JINI • JavaSpaces
Network programming • Historically error-prone, difficult, complex • but network programming in java is rather easy • IO stream library works quite well for TCP/IP. • Threading is also very useful and relatively easy here • References: • The java tutorial, Trail: Custom Networking • http://java.sun.com/docs/books/tutorial/index.html • Thinking in java, ch 15 http://www.eckelobjects.com/TIJ2/index.html. • “Java Network Programming” by Elliotte Rusty Harold, O’Reilly Books, 2nd Edition 2000. visit http://www.ibooks.com for a free online reference.
(Peer to Peer) Protocol interfaces InterNet physical layer physical layer Networking Basics • TCP/IP Network Protocol
TCP and UDP • TCP (Transmission Control Protocol) is a connection-based protocol that provides a reliable flow of data between two computers. • UDP (User Datagram Protocol) is a protocol that sends independent packets of data, called datagrams, from one computer to another with no guarantees about arrival. UDP is not connection-based like TCP.
Identifying a Machine • Uniquely identify a machine from all the others in the world • IP (Internet Protocol) address that can exist in two forms: • DNS (Domain Name System) form: xml.cs.nccu.edu.tw • “Dotted quad” (IP) form: 140.119.162.230 • Represented internally by 32-bit number (4 bytes) • 4.3 billion possibilities. • IPV6 : 128-bit coming… • static InetAddress.getByName(String) produces Java object containing address
server Client InputStream OutputStream OutputStream InputStream Socket connection (full duplex) Servers & Clients • Two machines must connect • Server waits around for connection • Client initiates connection • Once the connection is made, server & client look identical • Both ends are turned into InputStreamand OutputStreamobjects, which can then be converted to Reader and Writer objects
Testing w/o a Network • Here, we have no network • Also, you may not trust your program enough yet. • “localhost”: the “local loopback” IP address for testing without a network InetAddress addr = InetAddress.getByName(null); • Equivalently: InetAddress.getByName("localhost"); • Or using the reserved IP number for the loopback: InetAddress.getByName("127.0.0.1");
WhoAmI // Finds out your network address when // you're connected to the Internet. import java.net.*; public class WhoAmI { public static void main(String[] args) throws Exception { if(args.length != 1) { System.err.println( "Usage: WhoAmI MachineName"); System.exit(1); } InetAddress a = InetAddress.getByName(args[0]); System.out.println(a); } }
Port: Unique “Place” in a Machine • IP address isn’t enough to identify a unique server • Many servers can exist on one machine • IP machines also contain port numbers • When you set up client and server, you must specify IP address and port, so they can find each other • Not a physical location, but a software abstraction to represent a service • There are 65536 ports in a machine • 0-1023 reserved, others usable • 80 HTTP; 110 POP3; • 20,21 ftp; 25 smtp; • 23 telnet, 119 nntp …
server Client InputStream OutputStream OutputStream InputStream Socket connection (full duplex) Sockets • Software abstraction used to represent the “terminals” of a connection between two machines • Java provides a class abstraction : java.io.Socket • Socket is the actual 2-way connector. Can initiate a connection with a server • ServerSocket isn’t really a socket but more of a “ServerConnector” that produces a Socket as the return value of accept( ), which waits for a connection. • In the end, you get a Socket on each machine
Just Like Files... • Once you have a Socket, you call getInputStream( ) and getOutputStream( ) to produce the corresponding InputStream and OutputStream objects • You convert these to readers and writers, wrap them in a BufferedReader or BufferedWriter and PrintWriter • From then on, it’s like reading and writing any other IO stream!
Simple Server & Client //: Very simple server that just echoes whatever the client sends. import java.io.*; import java.net.*; public class JabberServer { // Choose a port outside of the range 0-1023: public static final int PORT = 8080; public static void main(String args[]) throws IOException { ServerSocket s = new ServerSocket(PORT); System.out.println("Started: " + s);
try { // Blocks until a connection occurs: Socket socket = s.accept(); try { System.out.println( "Connection accepted: "+ socket); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); // Output is automatically flushed by PrintWriter: PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter ( socket.getOutputStream())),true);
while (true) { // main server response String str = in.readLine(); if (str.equals("END")) break; System.out.println("Echoing: " + str); out.println(str); } // Always close the two sockets... } finally { System.out.println("closing..."); socket.close(); } } finally { s.close(); } } }
The client program // Thinking in Java c15, JabberClient.java // Very simple client that just sends lines to the server and reads lines // that the server sends. import java.net.*; import java.io.*; public class JabberClient { public static void main(String args[]) throws IOException { // "Local Loopback" IP address: InetAddress addr = InetAddress.getByName(null); System.out.println("addr = " + addr); // Unlike ServerSocket, client needn’t specify its local port, which is allocated dynamically by machine. Socket socket =new Socket(addr, JabberServer.PORT); // Guard everything in a try-finally to make sure that the socket is closed:
try { System.out.println("socket = " + socket); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); // Output is automatically flushed by PrintWriter: PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter (socket.getOutputStream() ) ), true); for(int i = 0; i < 10; i ++) { out.println(“sending " + i); String str = in.readLine(); System.out.println(str); } out.println("END"); } finally { System.out.println("closing..."); socket.close();} } }
Serving Multiple Clients via Threads // A server that uses multithreading to handle any number of clients. import java.io.*; import java.net.*; class ServeOneJabber extends Thread { private Socket socket; private BufferedReader in; private PrintWriter out; public ServeOneJabber(Socket s) throws IOException { socket = s; in = new BufferedReader( new InputStreamReader (socket.getInputStream())); // Enable auto-flush: out = new PrintWriter(new BufferedWriter( new OutputStreamWriter ( socket.getOutputStream())), true); // If any of the above calls throw an exception, the caller is responsible // for closing the socket. Otherwise the thread will close it. }
public void run() { try { while (true) { String str = in.readLine(); if (str.equals("END")) break; System.out.println("Echoing: " + str); out.println(str); } System.out.println("closing..."); } catch (IOException e) { } finally { try {socket.close(); } catch(IOException e) {} } } }
MultiJabberServer public class MultiJabberServer { static final int PORT = 8080; public static void main(String[] args) throws IOException { ServerSocket s = new ServerSocket(PORT); System.out.println("Server Started"); try { while(true) { // wait for a connection established: Socket socket = s.accept(); try { new ServeOneJabber(socket).start(); } catch(IOException e) { // If it fails, close the socket, otherwise the thread will close it: socket.close(); } } } finally { s.close(); } } }
JabberClientThread // Client that tests the MultiJabberServer by starting up multiple clients. import java.net.*; import java.io.*; class JabberClientThread extends Thread { private Socket socket; private BufferedReader in; private PrintWriter out; private static int counter = 0; private int id = counter++; private static int threadcount = 0; public static int threadCount() { return threadcount; } public JabberClientThread(InetAddress addr) { System.out.println("Making client " + id); threadcount++; try { socket = new Socket(addr, MultiJabberServer.PORT); } catch(IOException e) { // If the creation of the socket fails, nothing needs to be cleaned up. }
try { in = new BufferedReader( new InputStreamReader ( socket.getInputStream())); // Enable auto-flush: out = new PrintWriter( new BufferedWriter( new OutputStreamWriter( socket.getOutputStream())), true); start(); } catch(IOException e) { // The socket should be closed on any failures other than the socket // constructor: try { socket.close(); } catch(IOException e2) {} } // Otherwise the socket will be closed by // the run() method of the thread. }
public void run() { try { for(int i = 0; i < 25; i++) { out.println("Client " + id + ": " + i); String str = in.readLine(); System.out.println(str); } out.println("END"); } catch(IOException e) {} finally { // Always close it: try { socket.close();} catch(IOException e) {} threadcount--; // Ending this thread } } }
MultiJabberClient public class MultiJabberClient { static final int MAX_THREADS = 40; public static void main(String[] args) throws IOException, InterruptedException { InetAddress addr = InetAddress.getByName(null); while(true) { if(JabberClientThread.threadCount() < MAX_THREADS) new JabberClientThread(addr); Thread.currentThread().sleep(100); // Why not just sleep(100)? } } }
User Datagram Protocol (UDP) • Previous examples used Transmission Control Protocol (TCP). • Very high reliability, message will always get there. • Also high overhead • User Datagram Protocol (UDP) is an unreliable protocol which is much faster, but the messages won’t always get there
Datagrams • You make your own packets and write the address on the outside, send it • Based on packet contents, recipient decides whether they got everything, sends a message if they didn’t, and you retransmit in that case. • Reliability must be enforced by your program, not by the UDP protocol
Port Warning • Problem: program works fine, except when client is behind a firewall • Firewall doesn’t like to see anything but ordinary network connections to WWW server via its standard http port 80 • Servlets solve the problem
Access resources via URLs • What Is a URL ? • an acronym for Uniform Resource Locator • is a reference (an address) to a resource on the Internet. • Format: • scheme : [// [host [:port]]][ path [reference]] • EXs: • http://www.cs.nccu.edu.tw • http://xml.cs.nccu.edu.tw/Courses/java2002/index.html#loc2 • ftp://java.sun.com/pub/ • http://java.sun.com/servlet/app1?user=chen+passwd=**** • file:///D:/chencc/java2002/index.html
Creating a URL • Direct from URL address • String j2k = “http://xml.cs.nccu.edu.tw/Courses/java2000”; • URL j2000 = new URL(j2k); // or • URL j2000 = new URL • (“http”, “xml.cs.nccu.edu.tw”, “Courses/java2000”); • Relative to another URL address • String coursesLoc = “http://xml.cs.nccu.edu.tw/Courses/index.html” • URL coursesURL = new URL(coursesLoc); • URL j2000 = new URL(coursesURL, “java2002/index.html”); • Constructor Summary • URL(String spec) • URL(String scheme, String host [, int port] , String file [, URLStreamHandler h]) • URL(URL baseURL, String relativeURL [,URLStreamHandler] ) • possible exception: MalformedURLException
Parsing a URL • getProtocol • Returns the protocol identifier component of the URL. • getHost • Returns the host name component of the URL. • getPort • Returns the port number component of the URL. • The getPort method returns an integer that is the port number. • If the port is not set, getPort returns -1. • getFile • Returns the filename component of the URL. • getRef • Returns the reference component of the URL.
Example import java.net.*; import java.io.*; public class ParseURL { public static void main(String[] args) throws Exception { URL aURL = new URL("http://java.sun.com:80/docs/books/" + "tutorial/index.html#DOWNLOADING"); System.out.println("protocol = " + aURL.getProtocol()); System.out.println("host = " + aURL.getHost()); System.out.println("filename = " + aURL.getFile()); System.out.println("port = " + aURL.getPort()); System.out.println("ref = " + aURL.getRef()); } } • Here's the output displayed by the program: protocol = http host = java.sun.com filename = /docs/books/tutorial/index.html port = 80 ref = DOWNLOADING
Reading Directly from a URL • InputStream openStream();// return a stream for reading • EX: URL yahoo = new URL("http://www.yahoo.com/"); BufferedReader in = new BufferedReader( new InputStreamReader( yahoo.openStream()) ); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close();
Connecting to a URL • URLConnection openConnectino() throws IOException; • EX: try { URL yahoo = new URL("http://www.yahoo.com/"); URLConnection yahooConnection = yahoo.openConnection(); … } catch (MalformedURLException e) { // new URL() failed . . . } catch (IOException e) { // openConnection() failed . . . }
Reading from and Writing to a URLConnection • Reading from a URLConnection // like direct reading from URL using openStream() URL yahoo = new URL("http://www.yahoo.com/"); URLConnection yc = yahoo.openConnection(); BufferedReader in = new BufferedReader( new InputStreamReader( yc.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close();
Writing to a URLConnection • procedures • 1.Create a URL. • 2.Open a connection to the URL. • 3.Set output capability on the URLConnection. • 4.Get an output stream from the connection. This output stream is connected to the standard input stream of the cgi-bin script on the server. • 5.Write to the output stream. • 6.Close the output stream.
String stringToReverse = URLEncoder.encode(args[0]); URL url = new URL("http://java.sun.com/cgi-bin/backwards"); URLConnection connection = url.openConnection(); connection.setDoOutput(true); PrintWriter out = new PrintWriter( connection.getOutputStream()); out.println("string=" + stringToReverse); out.close(); BufferedReader in = new BufferedReader( new InputStreamReader( connection.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) System.out.println(inputLine); in.close();
JDBC • Java DataBase Connectivity • Allows you to write SQL without worrying about what brand of database you’re connecting to • Provides a simple interface for database programming
JDBC database URL • A string used to identify data source ( and parameters) • The format: • jdbc: <subprotocol> : <otherStuff> • “jdbc” means using JDBC • <subprotocol>: the name of the driver or the name of a database connectivity mechanism. • <otherStuff> : the database identifier. This varies with the database driver used. • the first subprotocol available is the “jdbc-odbc bridge,” specified by “odbc” • EX: String dbUrl = "jdbc:odbc://whitehouse.gov:5000/CATS;PWD=Hillary";
//: c15:Lookup.java // Looks up email addresses in a local database using JDBC import java.sql.*; public class Lookup { public static void main(String args[]) { String dbUrl = "jdbc:odbc:people"; String user = ""; String password = ""; try { // Load the driver (registers itself) Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver"); Connection c = DriverManager.getConnection ( dbUrl, user, password); Statement s = c.createStatement();
// SQL code: ResultSet r = s.executeQuery( "SELECT FIRST, LAST, EMAIL FROM people.csv people " + "WHERE (LAST='" + args[0] + "') " + " AND (EMAIL Is Not Null) " + "ORDER BY FIRST"); while(r.next()) { // Capitalization doesn't matter: System.out.println( r.getString("Last") + ", " + r.getString("fIRST") + ": " + r.getString("EMAIL") ); } } catch(Exception e) { e.printStackTrace(); } } }
Servlets • Servlets are to servers what applets are to browsers • Servlet API (a standard Java extension) is truly cross-platform • Substitute for CGI scripts • Easier to write, faster to run • Not tied to any platform-specific API • Better than CGI scripts • Stay resident: speed, persistent • information • Multithreading locks prevent collisions • Session tracking built in
Running servlets locally • Download the Tomcat implementation of Java Servlets and JSPs • http://jakarta.apache.org • Official Servlet/JSP distribution • Free! Part of Apache project • Will eventually be integrated into Apache to make it a true application server • Execute Tomcat.bat start
Works with both GET & POST import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class ServletsRule extends HttpServlet { int i = 0; // Servlet "persistence" public void service(HttpServletRequest req, HttpServletResponse res) throws IOException { PrintWriter out = res.getWriter(); out.print("<HEAD><TITLE>"); out.print("A server-side strategy"); out.print("</TITLE></HEAD><BODY>"); out.print("<h1>Servlets Rule! " + i++); out.print("</h1></BODY>"); out.close(); } }
Easy to get HTML form data // Dumps the name-value pairs of any HTML form import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; public class EchoForm extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.print("<h1>Your form contained:</h1>"); Enumeration flds = req.getParameterNames(); while(flds.hasMoreElements()) { String field = (String)flds.nextElement(); String value = req.getParameter(field); out.print(field + " = " + value + "<br>"); } out.close(); }
public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException { doGet(req, res); } }
One servlet, thread-per-request import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class ThreadServlet extends HttpServlet { int i; public void service(HttpServletRequest req, HttpServletResponse res) throws IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); synchronized( this) { try { Thread.currentThread().sleep(5000); } catch( InterruptedException e) {} } out.print("<h1>Finished " + i++ + "</h1>"); out.close(); } }
Java Server Pages (JSPs) • Servlets still require web pages • Why not combine only the essential servlet code with the HTML code? • Why not minimize the Java code you have to write? • Inspired by ASPs but much nicer • The easiest way to experiment with servlet properties • You can include special servlets, calls to Java libraries, etc.
Java Server Web Dev Kit • From java.sun.com, exceptionally easy to install and run • All you do is put .jsp files in the appropriate directory, point your web browser at them • JSP is automatically built, compiled and loaded on the first call, just like a servlet
Most code is built for you <html><body> <H1>The time in seconds is: <%= System.currentTimeMillis()/1000 %> </H1> </body></html> • Plenty of Java code is produced, +HTML • The ‘<%=’ coerces the resulting expression to a String • Code automatically rebuilt & recompiled when JSP source file changes
Basic JSP operations <%-- This JSP comment will not appear in the generated html --%> <%-- This is a JSP directive: --%> <%@ page import="java.util.*" %> <%-- These are declarations: --%> <%! long loadTime= System.currentTimeMillis(); Date loadDate = new Date(); int hitCount = 0; %> <html><body> <%-- The next several lines are the result of a JSP expression inserted in the generated html; the '=' indicates a JSP expression--%> <H1>This page was loaded at <%= loadDate %> </H1>