260 likes | 417 Views
Peter Jones. John Morris. Java Programming The Language of Now & the Future Clients and Servers including Internet connectivity, I/O and JDBC. John Morris and Peter Jones Department of Electrical and Electronic Engineering, University of Western Australia. Sockets.
E N D
Peter Jones John Morris Java ProgrammingThe Language of Now & the FutureClients and Serversincluding Internet connectivity,I/O and JDBC John Morris and Peter Jones Department of Electrical and Electronic Engineering, University of Western Australia
Sockets • Sockets are the “endpoints” of Internet connections • Socket constructors require Internet addresses • Socket( String host, int port ) throws UnknownHostException, IOException; • Socket(InetAddress address, int port) throws IOException; • ... and a host of other alternatives, see the API documentation! • Note: these constructors throw exceptions • Use them in a try { } catch .. block MachineA 0 0 Ports Internet Ports MachineB nnn nnn
Sockets • Note: these constructors throw exceptions • Use them in a try { } catch .. Block • Note: UnknownHostException is a subclass ofIOException • catch( IOException e ) alone would suffice String name = new String(“ciips.ee.uwa.edu.au”);try { Socket t = new Socket( name, 80 ); ... } catch( UnknownHostException e ) { System.out.println(“Unknown host:” + name ); } catch( IOException e ) { ... }
Aside: Datagrams, ... • Use aDatagramSocket • Constructor • DatagramSocket( int port ) throws IOException;creates a datagram socket on port • Methods void receive( DatagramPacket p ) throws IOException; void send( DatagramPacket p ) throws IOException; • DatagramPacket • Constructor • DatagramPacket( byte[] buf, int length, InetAddress add, int port ); • creates a packet to be sent to port at add • Methods • byte[] getData(); • void setData( byte[] buf ); • InetAddress getAddress();
Datagrams, ... • Use aDatagramSocket • Constructor • DatagramSocket( int port ) throws IOException;creates a datagram socket on port • Methods void receive( DatagramPacket p ) throws IOException; void send( DatagramPacket p ) throws IOException; • DatagramPacket • Constructor • DatagramPacket( byte[] buf, int length, InetAddress add, int port ); • creates a packet to be sent to port at add • Methods • byte[] getData(); • void setData( byte[] buf ); • InetAddress getAddress(); Note: byte[] not char[] ... more later!
Multicast sockets ... • Messages to multiple hosts • Use a MulticastSocket • ConstructorMulticastSocket( int port ) throws IOException;creates a datagram socket bound to port • Methods • void receive( DatagramPacket p ) throws IOException; • void send( DatagramPacket p ) throws IOException; • void joinGroup( InetAddress mcastaddr ) throws IOException; • void leaveGroup( InetAddress mcastaddr ) throws IOException; • Hosts can join and leave multicast groups • Security feature: • An applet is not allowed to use a multicast socket Inherited fromDatagramSocket
Talking to a server static final int lut_port = 3062;String name = new String(“ciips.ee.uwa.edu.au”); static final String query = “?”; try { Socket server = new Socket( name, lut_port ); DataInputStream input = new DataInputStream( server.getInputStream() ); PrintStream output = new PrintStream( server.getOutputStream() ); do { output.println( query ); String resp = input.readLine(); System.out.println( name + “ response: “ + resp ); } while ( !( resp.equal( quit_string ) ) ); server.close(); } catch( UnknownHostException e ) { System.out.println(“Unknown host:” + name ); } catch( IOException e ) { ... }
Talking to a server Socket(and almost all the rest)throws an exception, so put it all in a try { } block static final int lut_port = 3062;String name = new String(“ciips.ee.uwa.edu.au”); static final String query = “?”; try { Socket server = new Socket( name, lut_port ); DataInputStream input = new DataInputStream( server.getInputStream() ); PrintStream output = new PrintStream( server.getOutputStream() ); do { output.println( query ); String resp = input.readLine(); System.out.println( name + “ response: “ + resp ); } while ( !( resp.equal( quit_string ) ) ); server.close(); } catch( UnknownHostException e ) { System.out.println(“Unknown host:” + name ); } catch( IOException e ) { ... } Once the Sockethas been created, create input and output streams on it DataInputStream DataOutputStream PrintStream Just part of the stream zoo - there are 55 more!
Talking to a server static final int lut_port = 3062;String name = new String(“ciips.ee.uwa.edu.au”); static final String query = “?”; try { Socket server = new Socket( name, lut_port ); DataInputStream input = new DataInputStream( server.getInputStream() ); PrintStream output = new PrintStream( server.getOutputStream() ); do { output.println( query ); String resp = input.readLine(); System.out.println( name + “ response: “ + resp ); } while ( !( resp.equal( quit_string ) ) ); server.close(); } catch( UnknownHostException e ) { System.out.println(“Unknown host:” + name ); } catch( IOException e ) { ... } Now use methods on the streams just like any other I/O device println on PrintStream readLine on DataInputStream
Talking to a server • Finally add some code to handle exceptions! • Choices (Java usually gives you plenty ) • Separate catch blocks for different types • One “catch all” (IOException) • try { } catch { } for each method call • Throw the exception from here static final int lut_port = 3062;String name = new String(“ciips.ee.uwa.edu.au”); static final String query = “?”; try { Socket server = new Socket( name, lut_port ); DataInputStream input = new DataInputStream( server.getInputStream() ); PrintStream output = new PrintStream( server.getOutputStream() ); do { output.println( query ); String resp = input.readLine(); System.out.println( name + “ response: “ + resp ); } while ( !( resp.equal( quit_string ) ) ); server.close(); } catch( UnknownHostException e ) { System.out.println(“Unknown host:” + name ); } catch( IOException e ) { ... }
Talking to a server - variant 1 • Exception Choices (Java usually gives you plenty ) • try { } catch { } for each method call • Throw the exception from here static final int lut_port = 3062;String name = new String(“ciips.ee.uwa.edu.au”); static final String query = “?”; try { Socket server = new Socket( name, lut_port ); } catch( UnknownHostException e ) { System.out.println(“Unknown host:” + name ); return error_flag; } catch( IOException e ) { /* process other errors .... */ return error_flag; } try { DataInputStream input = new DataInputStream( server.getInputStream() ); PrintStream output = new PrintStream( server.getOutputStream() ); } catch( IOException e ) { System.out.println(“Cant form streams”); return error_flag; } do { /* do some real work ... */ try { } catch { } around each exception throwing call
Talking to a server - variant 2 • Exception Choices (Java usually gives you plenty ) • try { } catch { } for each method call • Throw the exception from here This method throws any exceptions up a level public String ServerResp( String query ) throws IOException { static final int lut_port = 3062; String name = new String(“ciips.ee.uwa.edu.au”); Socket server = new Socket( name, lut_port ); DataInputStream input = new DataInputStream( server.getInputStream() ); PrintStream output = new PrintStream( server.getOutputStream() ); output.println( query ); String resp = input.readLine(); server.close(); return resp; }
Simple Server static final int lut_port = 3062;static final int queue_len = 10;try { Socket server = new ServerSocket( lut_port, queue_len ); } catch( IOException e ) { System.out.println(“Can’t establish server on port “ + lut_port ); } while( true ) { // The server never dies! // Wait for a connection attempt try { Socket s = server.accept(); PrintStream ps = new PrintStream( s.getOutputStream() ); DataInputStream in = new DataInputStream( s.getInputStream() ); while( true ) { String q = in.readLine(); if ( q.equal( “?” ) ) ps.println( “Hello” ); else if ( q.equal( “quit” ) ) break; else ps.println( “??” ); } s.close(); // Close this connection } catch ( IOException e ) { /* Do something about it! */ } }
Simple Server Set up aServerSocket - basically just a socket with an accept method static final int lut_port = 3062;static final int queue_len = 10;try { Socket server = new ServerSocket( lut_port, queue_len ); } catch( IOException e ) { System.out.println(“Can’t establish server on port “ + lut_port ); } while( true ) { // The server never dies! // Wait for a connection attemtp try { Socket s = server.accept(); PrintStream ps = new PrintStream( s.getOutputStream() ); DataInputStream in = new DataInputStream( s.getInputStream() ); while( true ) { String q = in.readLine(); if ( q.equal( “?” ) ) ps.println( “Hello” ); else if ( q.equal( “quit” ) ) break; else ps.println( “??” ); } s.close(); // Close this connection } catch ( IOException e ) { /* Do something about it! */ } } Servers usually live forever!! The code will block here until a client attempts a connection
Simple Server static final int lut_port = 3062;static final int queue_len = 10;try { Socket server = new ServerSocket( lut_port, queue_len ); } catch( IOException e ) { System.out.println(“Can’t establish server on port “ + lut_port ); } while( true ) { // The server never dies! // Wait for a connection attemtp try { Socket s = server.accept(); PrintStream ps = new PrintStream( s.getOutputStream() ); DataInputStream in = new DataInputStream( s.getInputStream() ); while( true ) { String q = in.readLine(); if ( q.equal( “?” ) ) ps.println( “Hello” ); else if ( q.equal( “quit” ) ) break; else ps.println( “??” ); } s.close(); // Close this connection } catch ( IOException e ) { /* Do something about it! */ } } • Now we just • create the input & output streams • read and write to them • close the connection when we’re finished
Simple Server static final int lut_port = 3062;static final int queue_len = 10;try { Socket server = new ServerSocket( lut_port, queue_len ); } catch( IOException e ) { System.out.println(“Can’t establish server on port “ + lut_port ); } while( true ) { // The server never dies! // Wait for a connection attemtp try { Socket s = server.accept(); PrintStream ps = new PrintStream( s.getOutputStream() ); DataInputStream in = new DataInputStream( s.getInputStream() ); while( true ) { String q = in.readLine(); if ( q.equal( “?” ) ) ps.println( “Hello” ); else if ( q.equal( “quit” ) ) break; else ps.println( “??” ); } s.close(); // Close this connection } catch ( IOException e ) { /* Do something about it! */ } } But ... This server blocks whilst one user is using it! A second client can’t connect ‘til the first one finishes! Solution ... A thread for each client
Multi-threaded Server Make this parameter relevant! Number of queued requests static final int lut_port = 3062;static final int queue_len = 10;try { Socket server = new ServerSocket( lut_port, queue_len ); } catch( IOException e ) { System.out.println(“Can’t establish server on port “ + lut_port ); } while( true ) { // The server never dies! // Wait for a connection attempt try { Socket s = server.accept(); // This thread will do the talking ClientHandler ch = new ClientHandler( s ); ch.start(); } catch ( IOException e ) { /* Do something about it! */ } } As soon as we get a connection, spawn a handler thread to talk to the client Start the thread
Multi-threaded Server - The Handler This class is a Thread class ClientHandler extends Thread { Socket s; public ClientHandler( Socket s ) { this.s = s; } public void run() { PrintStream ps = new PrintStream( s.getOutputStream() ); DataInputStream in = new DataInputStream( s.getInputStream() ); while( true ) { String q = in.readLine(); if ( q.equal( “?” ) ) ps.println( “Hello” ); else if ( q.equal( “quit” ) ) break; else ps.println( “??” ); } s.close(); // Close this connection } } Constructor - just save a reference to the socket Same operational code .. Just embedded in the thread’s run method
I/O Streams - Too much choice? • There’s a bewildering array of choices ... “Stream Zoo” • Considering input .. • InputStream • ByteArrayInputStream • FileInputStream • FilterInputStream • BufferedInputStream • DataInputStream • DataInput • InflaterInputStream • GZIPInputStream • ZipInputStream • ... 3 more! • PipedInputStream • ... 3 more! Matching Output classes also!
I/O Streams - Too much choice? • ... and the Reader classes! • Characters (16 bits!) rather than bytes • Reader • BufferedReader • LineNumberReader • CharArrayReader • FilterReader • PushbackReader • InputStreamReader • FileReader • PipedReader • StringReader Matching Writer classes also!
Writing Objects to Streams • ObjectOutputStream • Enables writing of serialized objects • Serializable objects implement the java.io.Serializable interface • private void writeObject( ObjectOutputStream out ) throws IOException; • private void readObject( ObjectInputStream in ) throws IOException, ClassNotFoundException; • ClassNotFoundException? • A remote program could send you an object that you don’t know about .. • .. and therefore don’t know how to de-serialize!
Bytes and characters in Java • Java has • Primitive types • byte • char • Classes • Byte • Character • Class Byte has a single attribute of type byte • It’s just a class “wrapper” for a byte • Class Character ... • Characters are Unicode characters • For the full tables, see • ftp://ftp.unicode.org/Public • Character methods • isDigit, isLetter, isLowerCase, ... • Full story: Gosling, Joy & Steele, “The Java Language Specification”
Bytes and characters in Java • Class Character ... • Characters are Unicode characters • Main trap ... • “char” files created by other programs, eg C, C++ • Files created by text editors • ... but Windows “NotePad” often creates Unicode files for you! • Suggestion • Use byte / Byte if the file, stream, ... may be generated/read by any other language
URLs • Not surprisingly, Java provides good support for URLs • URL class • Constructors • URL( String spec ); • URL( String protocol, String host, int port, String file ); • URL( String protocol, String host, String file ); • Methods • Object getContent(); • Retrieve the whole file • URLConnection openConnection(); • Used when URLConnection subclasses, eg HttpURLConnection, JarURLConnection exist • InputStream openStream();
SQL databases • JDBC • provides a bridge to an Open Database Connectivity (ODBC) interface to a specific database • Getting started • import java.sql.*; • Load the bridge .. • Class.forName( “sun.jdbc.odbc.JdbcOdbcDriver” ); • Connect to a database • Connection c = DriverManager.getConnection( String URL, String username, String passwd ); • Create an SQL statement • Statement s = c.createStatement(); • Execute a statement • s.execute( String sql_statement );
SQL databases • JDBC • Results from a query • ResultSet res = s.executeQuery( String s ); • Goto the first row ... • res.next(); • Extract data • String name = res.getString( String col_name ); • int value = res.getInt( String col_name ); • ... and, of course, several pages more! • Examing the table returned • ResultSetMetaData m = res.getMetaData(); • Information about the table • int columns = m.getColumnCount(); • String label = m.getColumnLabel( int col_no ); • Columns number from 1! • String ctype = m.getColumnType( int col_no ); • ... and, of course, 19 more!