1 / 57

Advanced Java Networking/Reflection Unit 2

Advanced Java Networking/Reflection Unit 2. CMSC 291 Shon Vick. Agenda. Continue looking at Network programming examples Some more complicated Examples Examine Advanced I/O in some detail Start Looking at Object Reflection. Networking Continued.

liesel
Télécharger la présentation

Advanced Java Networking/Reflection Unit 2

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Advanced JavaNetworking/ReflectionUnit 2 CMSC 291 Shon Vick

  2. Agenda • Continue looking at Network programming examples • Some more complicated Examples • Examine Advanced I/O in some detail • Start Looking at Object Reflection

  3. Networking Continued • Last time we looked at a few simple example of networking using sockets • Lets look at them again, but this time lets look at them a bit more deeply • We said that one way to think of a socket is that it’s just some plumbing that connects a client and server

  4. If a socket is a pipe … We could conceptualize this like so: Ports Client Server The things flowing through the Plumbing The Socket Plumbing

  5. The Answer Is .. • A Number of things can conceptually flow through the pipe • We will focus on two: • Objects • Characters from a String • We looked at several examples last time • The first was a simple echo program – a very simple protocol – give me back what I gave you (Strings) • We also looked at simpleprotocol example (Protocol Objects)

  6. Objects flow through the Pipe • Let first address the case where we want to have objects flowing over the pipe • Must have at least the following there must be a mechanism for • Objects to be written by the server • Objects to be read by the client • Consider the newprotocol example from last time

  7. The newprotocol Client public class Client { Socket socket = new Socket( "127.0.0.1", 9999 ); // ObjectInputStream input = new ObjectInputStream(socket.getInputStream() ); // read using serialization NewProtocol protocol = (NewProtocol)(input.readObject() ); System.out.println(“Protocol: “ + protocol); socket.close();

  8. The newprotocol Server class ThreadedSocket extends Thread { // here is where all the real work is done. private Socket socket; ThreadedSocket( Socket socket ) { this.socket = socket; //… ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream() ); output.writeObject( protocol );

  9. Reading and Writing Objects • An ObjectOutputStream writes primitive data types and graphs of Java objects to an OutputStream. • The objects can be read (reconstituted) using an ObjectInputStream. • General Mechanism • This works for the sockets as was just shown but is actually more general • Persistent storage of objects can be accomplished by using a file for the stream.

  10. File example • For example to write an object that can be read by the example in ObjectInputStream FileOutputStream ostream = new FileOutputStream(“foo.bar"); ObjectOutputStream p = new ObjectOutputStream(ostream); p.writeInt(12345); p.writeObject("Today"); p.writeObject(new Date()); p.flush(); ostream.close();

  11. The read counterpart FileInputStream istream = new FileInputStream(" foo.bar "); ObjectInputStream p = new ObjectInputStream(istream); int i = p.readInt(); String today = (String)p.readObject(); Date date = (Date)p.readObject(); istream.close();

  12. The Needed Java Framework • Only objects that support the java.io.Serializable interface can be written to streams. • The class of each serializable object is encoded including the class name and signature of the class, the values of the object's fields and arrays, and the closure of any other objects referenced from the initial objects • This relates to introspection/reflection which we will discuss shortly

  13. More about the Framework • The default deserialization mechanism for objects restores the contents of each field to the value and type it had when it was written. • Marshalling of Objects (Serialize) • Un marshaling of Object (Serialize)

  14. Deserialization& Object Reflection • Fields declared as transient or static are ignored by the deserialization process. • References to other objects cause those objects to be read from the stream as necessary. • Graphs of objects are restored correctly using a reference sharing mechanism. • New objects are always allocated when deserializing, which prevents existing objects from being overwritten Reflection

  15. Reflection Allows • Determination of the class of an object. • Creation of an instance of a class whose name is not known until runtime. • Obtaining information about a class's modifiers, fields, methods, constructors, and superclasses. • Determination of constants and method declarations that belong to an interface

  16. Reflection Also Allows • Allows one to get and set the value of an object's field, even if the field name is unknown to your program until runtime. • Allows one to invoke a method on an object, even if the method is not known until runtime. • Create a new array, whose size and component type are not known until runtime, and then modify the array's components.

  17. Shooting Mesquites With Bazookas (Just Because You Have One) • Don't use the reflection API gratuitously when other Java tools would be more straight forward and natural • For example, if you use function pointers in another language, you might be tempted to use the Method objects of the reflection API in the same way. Resist the temptation! Your program will be easier to debug and maintain if you don't use Method objects. • Instead, you should define an interface, and then implement it in the classes that perform the needed action.

  18. Examining Classes • A way to get information about classes at runtime • For each class, the Java Runtime Environment (JRE) maintains an immutable Class object that contains information about the class. A Class object represents, or reflects, the class • To get this information you need to get the Class object that reflects the class

  19. Foo Bar Retrieving Class Objects You can retrieve a Class object in several ways: Class c = foo.getClass() // for some object named foo Bar b = new Bar(); Class c = b.getClass(); Class s = c.getSuperclass();

  20. Other Ways of Retrieving Class Objects • If you know the name of the class at compile time, you can retrieve its Class object by appending .class to its name: Class c = java.awt.Button.class; • You can also use the Class.forName static method: Class c = Class.forName(commandNameToken)

  21. Getting the Class Name • Every class in the Java programming language has a name. When you declare a class, the name immediately follows the class keyword • At runtime, you can determine the name of a Class object by invoking the getName method. The String returned by getName is the fully-qualified name of the class. • A good home study question: Given an instance prints the names of the classes its inheritance hierarchy from least specific to most specific excluding Object

  22. An Example import java.lang.reflect.*; import java.awt.*; class SampleName { public static void main(String[] args) { Button b = new Button(); printName(b); } static void printName(Object o) { Class c = o.getClass(); String s = c.getName(); System.out.println(s); }} Need Reflection Package To Do this

  23. Discovering Class Modifiers • A class declaration may include the following modifiers: public, abstract, or final. The class modifiers precede the class keyword in the class definition. In the following example, the class modifiers are public and final public final Coordinate { // … }

  24. Discovering Class Modifiers • To identify the modifiers of a class at runtime you perform these steps: • Invoke getModifiers on a Class object to retrieve a set of modifiers • Check the modifiers by calling isPublic, isAbstract, and isFinal • Lets look at an example

  25. First Part of the Example import java.lang.reflect.*; import java.awt.*; class SampleModifier { public static void main(String[] args) { String s = new String(); printModifiers(s); } // … }

  26. Second part of the example // …. public static void printModifiers(Object o) { Class c = o.getClass(); int m = c.getModifiers(); if (Modifier.isPublic(m)) System.out.println("public"); if (Modifier.isAbstract(m)) System.out.println("abstract"); if (Modifier.isFinal(m)) System.out.println("final"); } }

  27. Identifying the Interfaces Implemented by a Class import java.lang.reflect.*; import java.io.*; class SampleInterface { public static void main(String[] args) { try { RandomAccessFile r = new RandomAccessFile("myfile", "r"); printInterfaceNames(r); } catch (IOException e) { System.out.println(e); } }

  28. Continuing static void printInterfaceNames(Object o) { Class c = o.getClass(); Class[] theInterfaces = c.getInterfaces(); for (int i = 0; i < theInterfaces.length; i++) { String interfaceName = theInterfaces[i].getName(); System.out.println(interfaceName); } }

  29. There are mechanisms • Considerations of other dynamic properties • Identifying Class Fields • Discovering Class Constructors • Obtaining Method Information • Manipulating Objects • Working with Arrays • Summary of Classes

  30. Going with the Flow • So we have seen how Objects can flow across a Socket • Lets look again how character data can be used • This time with a more somewhat more sophisticated example

  31. Strings flowing through the Pipe • Say we want to have strings (i.e. character data) flowing over the pipe then there must be a mechanism for • Strings to be written by the server • Objects to be read by the client • Consider the Echo example from last time

  32. Echo Echo Echo import java.io.*; import java.net.*; public class EchoClient { public static void main(String[] args) throws IOException { Socket echoSocket = null; PrintWriter out = null; BufferedReader in = null; // …

  33. Establish the Socket connection Output Port Host try { echoSocket = new Socket(“avatar ", 7777); out = new PrintWriter(echoSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream())); } catch … Input

  34. Simple Socket Example Set up a mechanism to read from standard input BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in)); String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); System.out.println("echo: " + in.readLine()); } Read from standard input Write String to Server Read String that’s sent back from Server

  35. A String Based Protocol Server: "Knock knock!" Client: "Who's there?" Server: "Dexter." Client: "Dexter who?" Server: "Dexter halls with boughs of holly." Client: "Groan."

  36. The Knock Knock Protocol • The KnockKnockProtocol class implements the protocol that the client and server use to communicate. • This class keeps track of where the client and the server are in their conversation and serves up the server's response to the client's statements.

  37. Protocol Needs State and Constants import java.net.*; import java.io.*; public class KnockKnockProtocol { private static final int WAITING = 0; private static final int SENTKNOCKKNOCK = 1; private static final int SENTCLUE = 2; private static final int ANOTHER = 3; private static final int NUMJOKES = 5; private int state = WAITING; private int currentJoke = 0; Constants State

  38. Some More Invariants private static final String[] clues = { "Turnip", "Little Old Lady", "Atch", "Who", "Who" }; private static final String[] answers = { "Turnip the heat, it's cold in here!", "I didn't know you could yodel!", "Bless you!", "Is there an owl in here?", "Is there an echo in here?" };

  39. The Actual Protocol Part 1 public String processInput(String theInput) { String theOutput = null; if (state == WAITING) { theOutput = "Knock! Knock!"; state = SENTKNOCKKNOCK; } else if (state == SENTKNOCKKNOCK) { if (theInput.equalsIgnoreCase("Who's there?")) { theOutput = clues[currentJoke]; state = SENTCLUE; } else { theOutput = "You're supposed to say \"Who's there?\"! " + "Try again. Knock! Knock!";

  40. The Actual Protocol Part 2 } else if (state == SENTCLUE) { if (theInput.equalsIgnoreCase(clues[currentJoke] + " who?")) { theOutput = answers[currentJoke] + " Want another? (y/n)"; state = ANOTHER; } else { theOutput = "You're supposed to say \"" + clues[currentJoke] + " who?\"" + "! Try again. Knock! Knock!"; state = SENTKNOCKKNOCK; } } else if (state == ANOTHER) {

  41. The Actual Protocol Part 3 } else if (state == ANOTHER) { if (theInput.equalsIgnoreCase("y")) { theOutput = "Knock! Knock!"; if (currentJoke == (NUMJOKES - 1)) currentJoke = 0; else currentJoke++; state = SENTKNOCKKNOCK; } else { theOutput = "Bye."; state = WAITING; } } return theOutput; } }

  42. Using the Protocol • All client/server pairs must have some protocol by which they speak to each other; otherwise, the data that passes back and forth would be meaningless. • The protocol that your own clients and servers use depends entirely on the communication required by them to accomplish the task

  43. Use by the Client • The KnockKnockClient class implements the client program that speaks to the KnockKnockServer. KnockKnockClient is based on the Echo client we saw last time. • The communication between the client and the server • The server must first speak • Client must listen first

  44. Just like before we need both directions Socket kkSocket = new Socket(“avatar", 4444); // .. out = new PrintWriter(kkSocket.getOutputStream(), true); in = new BufferedReader( new InputStreamReader(kkSocket.getInputStream())); // …

  45. The Client Using the Protocol while ((fromServer = in.readLine()) != null) { System.out.println("Server: " + fromServer); if (fromServer.equals("Bye.")) break; fromUser = stdIn.readLine(); if (fromUser != null) { System.out.println("Client: " + fromUser); out.println(fromUser); } }

  46. The Server Using the Protocol • Server program begins by creating a new ServerSocket object to listen on a specific port • try { • serverSocket = new ServerSocket(4444); • } catch (IOException e) { • System.out.println("Could not listen on port: 4444"); • System.exit(-1); • }

  47. Wait for a connection Socket clientSocket = null; try { clientSocket = serverSocket.accept(); } catch (IOException e) { System.out.println("Accept failed: 4444"); System.exit(-1); }

  48. Set up the streams for the pipe PrintWriter out = new PrintWriter( clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader( clientSocket.getInputStream())); String inputLine, outputLine;

  49. Start the Conversation // initiate conversation with client KnockKnockProtocol kkp = new KnockKnockProtocol(); outputLine = kkp.processInput(null); out.println(outputLine);

  50. Use the Protocol while ((inputLine = in.readLine()) != null) { outputLine = kkp.processInput(inputLine); out.println(outputLine); if outputLine.equals("Bye.")) break; }

More Related