Title: Advanced Java NetworkingReflection Unit 2
1Advanced JavaNetworking/ReflectionUnit 2
2Agenda
- Continue looking at Network programming examples
- Some more complicated Examples
- Examine Advanced I/O in some detail
- Start Looking at Object Reflection
3Networking 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
its just some plumbing that connects a client
and server
4If a socket is a pipe
- We could conceptualize this like so
Ports
Client
Server
The things flowing through the Plumbing
The Socket Plumbing
5The 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)
6Objects 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
7The 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()
8The newprotocol Server
class ThreadedSocket extends Thread // here is
where all the real work is done. private Socket
socket public void run ( )
ThreadedSocket( Socket socket ) this.socket
socket // ObjectOutputStream
output new ObjectOutputStream(socke
t.getOutputStream() )
output.writeObject( protocol )
This is invoked with start() method
9Reading 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.
10File example
- For example to write an object that can be read
by the example in ObjectInputStream
FileOutputStream ostream new FileOutputStream(f
oo.bar") ObjectOutputStream p new
ObjectOutputStream(ostream) p.writeInt(12345) p.
writeObject("Today") p.writeObject(new
Date()) p.flush() ostream.close()
11The read counterpart
FileInputStream istream new
FileInputStream(" foo.bar ")
ObjectInputStream p new ObjectInputStream(istrea
m) int i p.readInt() String
today (String)p.readObject() Date date
(Date)p.readObject() istream.close()
12The 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
13More 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)
14Deserialization 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
15Reflection 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
16Reflection 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.
17Shooting Flies 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.
18Examining 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
19Retrieving 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()
Foo
Bar
20Other 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
for some string commandNameToken
Class c Class.forName(commandNameToken)
21Getting 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,
print the names of the classes in its inheritance
hierarchy from least specific to most specific
excluding the Object class
22An 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
)
23Discovering 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 //
24Discovering 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
25First 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)
//
Need Reflection Package To Do this
26Second 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")
27Identifying 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)
28Continuing
static void printInterfaceNames(Object o)
Class c o.getClass()
Class theInterfaces c.getInterfaces()
for (int i 0 i lt theInterfaces.length
i) String interfaceName
theInterfacesi.getName()
System.out.println(interfaceName)
29There are mechanisms
- Considerations of other dynamic properties
- Identifying Class Fields
- Discovering Class Constructors
- Obtaining Method Information
- Manipulating Objects
- Working with Arrays
- Summary of Classes
30Going 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
31Strings 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
32Echo 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 //
33Establish the Socket connection
Output
Port
Host
try echoSocket new Socket(avatar ",
7777) out new PrintWriter(echoSocket.getOutp
utStream(), true) in new
BufferedReader(new
InputStreamReader(echoSocket.getInputStream()))
catch
Input
34Simple 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 thats sent back from Server
35A String Based Protocol
Server "Knock knock!" Client "Who's
there?" Server "Dexter." Client
"Dexter who?" Server "Dexter halls with
boughs of holly." Client "Groan."
36The 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.
37Protocol 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
38Some 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?"
39The 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 cluescurrentJoke
state SENTCLUE else
theOutput "You're supposed to
say \"Who's there?\"! " "Try
again. Knock! Knock!"
40The Actual Protocol Part 2
else if (state SENTCLUE) if
(theInput.equalsIgnoreCase(cluescurrentJoke "
who?")) theOutput
answerscurrentJoke " Want another? (y/n)"
state ANOTHER else
theOutput "You're supposed to say
\""
cluescurrentJoke
" who?\"" "! Try
again. Knock! Knock!" state
SENTKNOCKKNOCK else if
(state ANOTHER)
41The 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
42Using 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
43Use 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
44Just 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())) //
45The Client Using the Protocol
while ((fromServer in.readLine()) ! null)
System.out.println("Server "
fromServer) if (fromServer.equals("By
e.")) break
fromUser stdIn.readLine()
if (fromUser ! null)
System.out.println("Client " fromUser)
out.println(fromUser)
46The 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)
-
47Wait for a connection
Socket clientSocket null try
clientSocket serverSocket.accept()
catch (IOException e)
System.out.println("Accept failed 4444")
System.exit(-1)
48Set up the streams for the pipe
PrintWriter out new PrintWriter(
clientSocket.getOutpu
tStream(), true) BufferedReader in
new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()))
String inputLine, outputLine
49Start the Conversation
// initiate conversation with client
KnockKnockProtocol kkp
new KnockKnockProtocol() outputLine
kkp.processInput(null)
out.println(outputLine)
50Use the Protocol
while ((inputLine in.readLine()) ! null)
outputLine kkp.processInput(inputLi
ne) out.println(outputLine)
if outputLine.equals("Bye."))
break
51Recap
- We continued looking at Network programming
examples from two perspectives by looking at some
complicated, techniques, and protocols - Examine Advanced I/O in some detail
- Looked at Object Reflection and its role in
serialization
52What to do for Next Time
- Do the Programming Homework Due next Thursday
- Continue reading chapters 2,3, 1
- Study for Quiz Take Home portion will be Posted
by Sunday 1/12
53Homework Due Thursday 1/16
- 1.1 Implement a client server that implements a
protocol for a simple subset (of your choosing)
of Eliza protocol (There are many many
implementations of Eliza check out these
references http//web.mit.edu/STS001/www/Team7/eli
za.html or http//chayden.net/eliza/Eliza.shtml
.. ) -
- 1.2 Conduct an experiment to see the
costs/benefits of Object flows vs.. String flows
across a socket - Vary the number of strings and Objects sent
- Time it use System.currentTimeMillis()
- Plot it (use tool of choice trivial in Excel)
- Analyze it
54Homework
- 1.3 Implement a Pyscho Friends Network (forgive
the pun) that allows the Eliza psychologist to
treat more than one patient at a time (see
http//java.sun.com/docs/books/tutorial/networking
/sockets/clientServer.htmllater for a hint on
how this could be accomplished
55Selected References
- Netwoking with Sockets
- Advanced Techniques for Java Developers Chapter
4 - http//java.sun.com/products/jdk/1.2/docs/api/java
/io/ObjectInputStream.html - http//java.sun.com/docs/books/tutorial/networking
/index.html
56More References
- Reflection
- The Java Programming Language , K.Arnold and J.
Gosling , Addison-Wesley , 1996 - Exploring Java . OReilly
- http//java.sun.com/docs/books/tutorial/reflect/in
dex.html - http//java.sun.com/docs/overviews/java/java-overv
iew-1.html - Miscellaneous
- http//java.sun.com/products/jdk/1.2/docs/