GSAMS Java Networking Networking Topics Overview A Short

  • Slides: 102
Download presentation
GSAMS Java Networking

GSAMS Java Networking

Networking Topics • Overview: A Short History of Java Networking – Where from; where

Networking Topics • Overview: A Short History of Java Networking – Where from; where to; “Are We There Yet? ” • Competing Networking Models: OSI v. Internet – Whose Kung Fu is Better? • Network Protocols in Java: – – TCP UDP Multicast Threaded and Non-Threaded examples • Remote Method Invocation (RMI)

A Short History of Java Networking • The Dark Ages: C/C++ Networking and the

A Short History of Java Networking • The Dark Ages: C/C++ Networking and the Need for Change – Before Java, simple network connectivity required lots of code. – C/C++ provided many, many choices/options for networking • Good for C programmers. • Most programmers did not use all these options. • Java 1. 0 Reflects Java’s non-academic motivations – Basic networking capability with high level abstraction of URL handlers. – Low level choices were missing (e. g. , connection timeouts. ) – Raw socket classes were final--java. net. Socket and java. net. Server. Socket could not be extended. – “One shot” implementations with java. net. Socket. Impl allowed only one implementation in each VM.

A Short History of Java Networking • JDK 1. 1 (the big leap) –

A Short History of Java Networking • JDK 1. 1 (the big leap) – Added four common socket options. – Allowed raw data manipulations within high-level abstractions. – Removed final designations. – Added multicast connections (previously limited to LAN and/or external native calls). • JDK 1. 2 (a second big leap) – Addition of fine-grained Java Security Model. • ability to control processes/connections/ports with very fine granular control over details. – Added functionality to APIs.

Competing Networking Models: OSI vs. Internet Whose Kung Fu is Better? • Two competing

Competing Networking Models: OSI vs. Internet Whose Kung Fu is Better? • Two competing models are used to describe networking – Open Systems Interconnection (OSI) architecture – Internet Architecture • Open Systems Interconnection Standard – partitions network connectivity into seven layers. – published by OSI and International Telecommunications Union (ITU) in series of “X dot” standards: X. 25, X. 400, etc. • Internet Architecture Standard – also known as “TCP/IP architecture” after its two key protocols – evolved from packet-switched ARPANET of Do. D – Internet Engineering Task Force (IETF) maintenance.

A Comparison of the OSI Seven Layer Model and the Taco Bell Seven Layer

A Comparison of the OSI Seven Layer Model and the Taco Bell Seven Layer Burrito Application Presentation Session Transport Network Data in use Syntax Packet recovery; sessions between applications Message quality; end-to-end error correction Packet routing; network connections Sour Cream Cheese Guacamole Tomatoes Lettuce Data Link Bit level organization; reliability Seasoned Rice Physical Media, electrical properties Refried Beans

End Host Application OSI in Action Network traffic in the OSI model must always

End Host Application OSI in Action Network traffic in the OSI model must always travel up and down the protocol stack to be routed. End Host Application Presentation Session Transport Nodes in Network Transport Network Data Link Physical

Internet Architecture Model Design theory: “rough consensus and running code” Application Protocols Transport Protocols

Internet Architecture Model Design theory: “rough consensus and running code” Application Protocols Transport Protocols (TCP/UDP) Internet Protocol (IP) Network Protocols The IETF culture requires that new layers provide a protocol specification and at least two or three running implementations. Likely, the four layer model will not grow in complexity (unless the internet does first. )

Internet Architecture Model The Internet Architecture is also flexible; applications can reach the network

Internet Architecture Model The Internet Architecture is also flexible; applications can reach the network layer directly, or work through protocols such as TCP/UDP and IP APPLICATION TCP UDP IP NETWORK

Internet Architecture Model Transport through each layer requires the use of additional headers. Application

Internet Architecture Model Transport through each layer requires the use of additional headers. Application Layer DATA Transport Layer Internet Layer Network Layer HEADER DATA HEADER DATA

Network Protocols in Java In terms of protocols and services, Java offers API support

Network Protocols in Java In terms of protocols and services, Java offers API support for three basic types of connectivity: TCP -- Transport Control Protocol UDP -- User Datagram Protocol java. net package Mcast -- Multicast Protocol. -- Basic Terminology -A Socket is an abstraction of a "communications link" between machines over some network. Socket communication is the same regardless of whether the network connection is via a phone line, cable modem, ethernet, or fiber-optic line. A packet is a discrete quantity of information suitable for routed transport over a shared network. Packet sizes are limited, so a packet may be a fragment of a large file or message.

Basic Terminology (cont’d) Naming and Addressing The “IPv 4” addressing scheme uses 32 -bit

Basic Terminology (cont’d) Naming and Addressing The “IPv 4” addressing scheme uses 32 -bit addresses, often presented as a set of four octets. Read from left to right, we progressively define a particular machine: 192. 168. 1. 200 The “dotted quad” or “dotted decimal” format is quite common. Numbering is controlled by the Internet Assigned Numbers Authority (IANA), and later the Internet Corporation for Assigned Names and Numbers (ICANN).

IP Address Classes A 127. 0. 0. 0 and below First bit == 0

IP Address Classes A 127. 0. 0. 0 and below First bit == 0 B 127. 0. 1. 0 to 191. 255 First bits == 1 0 C 192. 0. 1. 0 to 223. 255 First bits == 1 1 0 D Not allocated to networks -- mcast First bits == 1 1 1 0 E 240. 0 and above; not assigned First bits == 1 1 Special numbers: 127. 0. 0. 1 -- used for loopback addresses 192. 168. x. x -- class B private networks 10. x. x. x. -- class A private networks

IP Address Classes The IPv 4 address scheme is limited by potentially wasteful address

IP Address Classes The IPv 4 address scheme is limited by potentially wasteful address allocation. For example, the jump from class C (one octet, or ~254 addresses) to class B (two octets, or ~65334 addresses) is quite large. So, a company with more than 250 computers might request a class B address, but use far less than the ~65, 000 possible combinations. This inefficiency consumes the address space quickly. Solutions include more efficient number allocations, ip chaining (firewalls), and migration to IPv 6 (128 bit address), . . . even IPv 8. Java’s underlying native code has support for IPv 6, so it will be ready if/when companies (notably Cisco) decide to embrace IPv 6.

IP Addresses: Names To make IP addresses readable, a table of names is used

IP Addresses: Names To make IP addresses readable, a table of names is used to represent IP numbers. The names are in a hierarchical order; however, there is no one-to-one mapping between name hierarchies and dotted quad number hierarchies. DNS, or Domain Name Service, provides a name to IP addressing service. . net gov mil (Root) org com edu On a Unix machine, one often uses “nslookup” or some similar program to covert between names and numbers.

Ports Most computers have a single network connection used for all data. Most operating

Ports Most computers have a single network connection used for all data. Most operating systems allow multi-tasking, so several network applications can be running at once. How does the computer know which application gets the data? Ports allow us to specify specific applications on the host. The TCP and UDP protocols attach port information (16 bit number) to each packet. Machine 2 Machine 1 Machine 3 Thus, when creating connections between computers, we need an IP address as well as the port to specify the machine and client process

The java. net. * Package Key Classes: java. net. Inet. Address IP Address structures,

The java. net. * Package Key Classes: java. net. Inet. Address IP Address structures, and services java. net. Server. Socket This class implements server sockets. java. net. Socket This class implements client sockets (also called just "sockets"). java. net. URL Class URL represents a Uniform Resource Locator, a pointer to a "resource" on the World Wide Web.

Address representations java. net. Inet. Address: -- A class representing an IP address --

Address representations java. net. Inet. Address: -- A class representing an IP address -- Performs validity checking on IP names -- Thus, there are no public constructors! -- Instead, just call a static class method to obtain an Inet. Address: Inet. Address has no public constructors since it performs validity checking of all IP names import java. net. *; public class My. Machine. Name { public static void main (String arg[]){ Inet. Address local = null; try { local = Inet. Address. get. Local. Host(); } catch (Unknown. Host. Exception e){ System. err. println ("Identity Crisis!"); System. exit(0); } String str. Address = local. get. Host. Name(); System. out. println ("Local Host = " + str. Address); } }

Converting IP Numbers to Strings import java. net. *; This does things public class

Converting IP Numbers to Strings import java. net. *; This does things public class My. Machine. Name { the hard way! public static void main (String arg[]){ Inet. Address local = null; Just call try { get. Host. Address() local = Inet. Address. get. Local. Host(); instead! } catch (Unknown. Host. Exception e){ System. err. println Lesson: Java’s ("Identity Crisis!"); net package has most System. exit(0); every method you } will need! byte[] b = local. get. Address(); String str. Address=“”; for (int i = 0; i < b. length; i++) str. Address += ((int)255 & b[i]) + “. ”; System. out. println (“Local = “ + str. Address); } }

Other Inet. Address Services public boolean is. Multicast. Address(); static Inet. Address[] get. All.

Other Inet. Address Services public boolean is. Multicast. Address(); static Inet. Address[] get. All. By. Name(String host); Determines all the IP addresses of a host, given the host's name. static Inet. Address get. By. Name(String host); Determines the IP address of a host, given the host's name. Let’s duplicate the basic service of the Unix command “nslookup” in Java. This will allow us to convert any IP name into its valid IP number. (We won’t support the -opt switches, to keep things simple. ) From the Unix “nslookup man page(1 M)”: “nslookup is an interactive program to query ARPA Internet domain name servers. The user can contact servers to request information about a specific host, or print a list of hosts in the domain. ”

import java. net. *; public class nslookup { public static void main(String arg[]){ if

import java. net. *; public class nslookup { public static void main(String arg[]){ if (arg. length == 0) show. Usage(); Inet. Address[] names = null; try{ names = Inet. Address. get. All. By. Name(arg[0]); } catch (Unknown. Host. Exception e){ System. err. println("Error: Unknown Host: " + arg[0]); System. exit(1); } for (int i=0; i< names. length; i++) System. out. println ("n. Name: " + names[i]. get. Host. Name() + "n. Address: " + names[i]. get. Host. Address()); }//main public static void show. Usage(){ System. out. println ("Usage: ntnslookup <ip name>"); System. exit(0); }//show. Usage }//nslookup

Sockets. . . and Threads Sockets -- The Basics: TCP -- The Not-So-Basics --

Sockets. . . and Threads Sockets -- The Basics: TCP -- The Not-So-Basics -- The Basics: UDP Quick Notes on Threads -- A Threaded Example

Sockets A java. net. Socket provides an easy interface to a TCP connection. Of

Sockets A java. net. Socket provides an easy interface to a TCP connection. Of the eight Socket constructors, there are generally four commonly used: public Socket(Inet. Address address, int port); Creates a stream socket and connects it to the specified port number at the specified IP address. public Socket(Inet. Address address, int port, Inet. Address local. Addr, int local. Port); Creates a socket and connects it to the specified remote address on the specified remote port. public Socket(String host, int port); Creates a stream socket and connects it to the specified port number on the named host. public Socket(String host, int port, Inet. Address local. Addr, int local. Port); Creates a socket and connects it to the specified remote host on the specified remote port.

Sockets Additionally, there are several commonly used Socket methods: public Input. Stream get. Input.

Sockets Additionally, there are several commonly used Socket methods: public Input. Stream get. Input. Stream(); Returns an input stream for this socket. public Output. Stream get. Output. Stream(); Returns an output stream for this socket. The streams returned from these accessors rely on TCP’s error correction and flow control. public void close(); Closes this socket. public int get. Port(); Returns the remote port to which this socket is connected. public Inet. Address get. Inet. Address(); Returns the address to which the socket is connected. public int get. Local. Port(); Returns the local port to which this socket is bound.

Sockets: Simple Usage We can therefore create a simple Socket with: Socket s =

Sockets: Simple Usage We can therefore create a simple Socket with: Socket s = new Socket (“acme. gatech. edu”, 13); We can obtain a Stream for receiving information with: Input. Stream in = s. get. Input. Stream(); We can obtain a stream for sending information with: Output. Stream out = s. get. Output. Stream();

Socket Options in Java Often, it is necessary to change basic features in Sockets.

Socket Options in Java Often, it is necessary to change basic features in Sockets. Berkeleyderived sockets allow one to set various standard options Some options are available only for Server. Sockets (explained later). Standard socket options available in Java include: SO_LINGER -- The “Socket Option Linger”; for when a close call catches material still in the send buffer SO_TIMEOUT -- The “Socket Option Timeout”; determines how long a connection may be idle before timeout. TCP_NODELAY -- The so-called “Nagle’s Algorithm” option; useful for WAN-based applications where small packets are likely (rlogin, ssh, telnet, etc. ), and limited window sizes will lead to delay.

Socket Options in Java public void set. So. Linger(boolean on, int linger); Enable/disable SO_LINGER

Socket Options in Java public void set. So. Linger(boolean on, int linger); Enable/disable SO_LINGER with the specified linger time in seconds. public void set. So. Timeout(int timeout); Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. public void set. Tcp. No. Delay(boolean on); Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm). public int get. So. Linger(); Returns setting for SO_LINGER. public int get. So. Timeout(); Returns setting for SO_TIMEOUT. public boolean get. Tcp. No. Delay(); Tests if TCP_NODELAY is enabled. public void set. Send. Buffer. Size(int size); Sets the SO_SNDBUF option to the specified value for this Datagram. Socket.

TCP/UDP Connections Distinguished The foregoing examples used TCP connections: session oriented connections with a

TCP/UDP Connections Distinguished The foregoing examples used TCP connections: session oriented connections with a high degree of congestion control and error correction. The Socket abstraction hides the Socket. Impl class, which provides these services. To that extent, TCP is said to provide “reliable” services. unreliable but fast Datagram TCP error correction; reliable TCP There may be circumstances where we don’t want the overhead associated with reliability. UDP, user datagram protocol, allows us to use so-called ‘unreliable’ networking services. UDP is a datagram-oriented protocol, meaning there is no session.

A Day Time Client From RFC 867 (J. Postel, 1983): “One daytime service is

A Day Time Client From RFC 867 (J. Postel, 1983): “One daytime service is defined as a connection based application on TCP. A server listens for TCP connections on TCP port 13. Once a connection is established the current date and time is sent out the connection as a ascii character string (and any data received is thrown away). The service closes the connection after sending the quote. ” Thus, we simply write a program to connect to a server’s port 13, and output the message.

import java. net. *; import java. io. *; public class Day. Time. Client {

import java. net. *; import java. io. *; public class Day. Time. Client { public static final int i. DAY_TIME_PORT = 13; // RFC 867 public static final int BUFF = 256; public static void main (String arg[]) throws Exception { if (arg. length == 0) show. Usage(); Socket sock = new Socket(arg[0], i. DAY_TIME_PORT); Input. Stream is = sock. get. Input. Stream(); int i; byte[] b = new byte[BUFF]; while ( (i=is. read(b)) != -1) System. out. println(new String(b, 0, i)); } public static void show. Usage(){ System. err. println ("Usage: ntjava Day. Time. Client <IP Address>"); System. exit(0); }//show. Usage }//class Day. Time. Client

Reading and Writing From Sockets in Java are full duplex--meaning that they can both

Reading and Writing From Sockets in Java are full duplex--meaning that they can both send and receive information. A good example of this feature is an echo client. The echo service listens to Port 7, and simply returns or ‘echoes back’ all information received from the client. An echo client, therefore, has to be able to send and receive over the same socket. Let’s look at an echo client written by Sun. .

public class Echo. Client { public static void main(String[] args) throws IOException { Socket

public class Echo. Client { public static void main(String[] args) throws IOException { Socket echo. Socket = null; Print. Writer out = null; Buffered. Reader in = null; try { echo. Socket = new Socket("taranis", 7); out = new Print. Writer(echo. Socket. get. Output. Stream(), true); in = new Buffered. Reader(new Input. Stream. Reader( echo. Socket. get. Input. Stream())); } catch (Unknown. Host. Exception e) { System. err. println ("Don't know about host: taranis. "); System. exit(1); } catch (IOException e) { System. err. println("Couldn't get I/O for " + "the connection to: taranis. "); System. exit(1); } Source: http: //www. javasoft. com

Buffered. Reader std. In = new Buffered. Reader(new Input. Stream. Reader(System. in)); String user.

Buffered. Reader std. In = new Buffered. Reader(new Input. Stream. Reader(System. in)); String user. Input; while ((user. Input = std. In. read. Line()) != null) { out. println(user. Input); System. out. println ("echo: " + in. read. Line()); } out. close(); in. close(); std. In. close(); echo. Socket. close(); } }

Analysis and An Idea COMMENTS: The entire program is a single static method (This

Analysis and An Idea COMMENTS: The entire program is a single static method (This is fine for an example). The program seems to repeat much of the code from our example. In fact, at some level this resembles most IO stream handlers. IDEA: Let’s abstract out the common stream handling features, and make a client that reads from/writes to a stream. We can then use this client for a variety of purposes. NOTION: We should thread the class we create. The need for threading requires more explanation.

Server. Sockets We may also wish to have a process listening on a port

Server. Sockets We may also wish to have a process listening on a port for incoming calls. Perhaps we’ve written a web browser that stands ready to send HTML content when a connection is made. The Server. Socket class allows us to capture incoming calls. Server. Socket out. Sock = new Server. Socket (6000); while (true) { Socket in. Sock = out. Sock. accept(); handle. Connection(in. Sock); in. Sock. close(); }

Server. Sockets public Server. Socket(int port); Creates a server socket on a specified port.

Server. Sockets public Server. Socket(int port); Creates a server socket on a specified port. public Server. Socket(int port, int backlog); Creates a server socket and binds it to the specified local port number. public Server. Socket (int port, int backlog, Inet. Address bind. Addr); Create a server with the specified port, listen backlog, and local IP address to bind to. public Socket accept(); Listens for a connection to be made to this socket and accepts it. public void close(); Closes this socket. public Inet. Address get. Inet. Address(); Returns the local address of this server socket.

Blocking Network Calls When using Server. Sockets, be aware: the call to “accept()” causes

Blocking Network Calls When using Server. Sockets, be aware: the call to “accept()” causes the program to wait until the method returns. This “blocking call” can cause a program to hang. Server. Socket serv. Sock = new Server. Socket (6000); while (true) { Socket in. Sock = serv. Sock. accept(); handle. Connection(in. Sock); in. Sock. close(); } If other operations must take place, we need some way of placing the “accept()” call in its own thread.

Threads Quickly, Incompletely Defined: A Thread is a lightweight process (chunk of code) that

Threads Quickly, Incompletely Defined: A Thread is a lightweight process (chunk of code) that can act independently of another any other code in an application. They allow us to give the illusion that more than one process is running at the same time. How-To in Java: Subclass java. lang. Thread, or implement the interface Runnable and provide a method: public void run() { // threaded code goes here } The method run() is started via a call to “start()”. (One can also override start(), but this is not always necessary. )

Simple Threads Example public class Clock extends Thread { String str. Sound; public Clock(String

Simple Threads Example public class Clock extends Thread { String str. Sound; public Clock(String str. Sound){ Note use of infinite loop this. str. Sound = str. Sound; in the run() method } public void run(){ while (true){ System. out. println (str. Sound); try{ this. sleep(1000); }// DOES NOT BLOCK catch (Interrupted. Exception e){} } } This code can run while other threads are being run! public static void main (String arg[]){ Clock c 1 = new Clock("Tick"); Clock c 2 = new Clock("Tock"); c 1. start(); c 2. start(); } }// class Clock Order of execution between c 1 and c 2 is not guaranteed!

Thread Issues Race Conditions: Access to shared objects may result in race conditions. One

Thread Issues Race Conditions: Access to shared objects may result in race conditions. One can guard against this mutexing or synchronizing blocks of code: public synchronized void increase. Account(){ // mutexed operations } Deadlocks: Pervasive use of semaphores can, if improperly designed, result in deadlock conditions.

Threaded Socket Clients Using these principles, we can design a simple client that opens

Threaded Socket Clients Using these principles, we can design a simple client that opens a TCP socket, and has facilities for reading/writing to the socket. Socket. Client Interface Socket. Client. Constants Interface Default. Socket. Client Class The key is that the client class Threads itself--preventing it from blocking other code.

Threaded Socket Clients: Interfaces public interface Socket. Client. Interface { boolean open. Connection(); void

Threaded Socket Clients: Interfaces public interface Socket. Client. Interface { boolean open. Connection(); void handle. Session(); void close. Session(); } public interface Socket. Client. Constants { int i. ECHO_PORT = 7; int i. DAYTIME_PORT = 13; int i. SMTP_PORT = 25; boolean DEBUG = true; }

import java. net. *; import java. io. *; public class Default. Socket. Client extends

import java. net. *; import java. io. *; public class Default. Socket. Client extends Thread implements Socket. Client. Interface, Socket. Client. Constants { private private Buffered. Reader reader; Buffered. Writer writer; Socket sock; String str. Host; int i. Port; public Default. Socket. Client(String str. Host, int i. Port) { set. Port (i. Port); set. Host (str. Host); }//constructor public void run(){ if (open. Connection()){ handle. Session(); close. Session(); } }//run

public boolean open. Connection(){ try { sock = new Socket(str. Host, i. Port); }

public boolean open. Connection(){ try { sock = new Socket(str. Host, i. Port); } catch(IOException socket. Error){ if (DEBUG) System. err. println ("Unable to connect to " + str. Host); return false; } try { reader = new Buffered. Reader (new Input. Stream. Reader(sock. get. Input. Stream())); writer = new Buffered. Writer (new Output. Stream. Writer (sock. get. Output. Stream())); } catch (Exception e){ if (DEBUG) System. err. println ("Unable to obtain stream to/from " + str. Host); return false; } return true; }

public void handle. Session(){ String str. Input = ""; if (DEBUG) System. out. println

public void handle. Session(){ String str. Input = ""; if (DEBUG) System. out. println ("Handling session with " + str. Host + ": " + i. Port); try { while ( (str. Input = reader. read. Line()) != null) handle. Input (str. Input); } catch (IOException e){ if (DEBUG) System. out. println ("Handling session with " + str. Host + ": " + i. Port); } } public void send. Output(String str. Output){ try { writer. write(str. Output, 0, str. Output. length()); } catch (IOException e){ if (DEBUG) System. out. println ("Error writing to " + str. Host); } }

public void handle. Input(String str. Input){ System. out. println(str. Input); } public void close.

public void handle. Input(String str. Input){ System. out. println(str. Input); } public void close. Session(){ try { writer = null; reader = null; sock. close(); } catch (IOException e){ if (DEBUG) System. err. println ("Error closing socket to " + str. Host); } } public void set. Host(String str. Host){ this. str. Host = str. Host; } public void set. Port(int i. Port){ this. i. Port = i. Port; }

public static void main (String arg[]){ /* debug main; does daytime on local host

public static void main (String arg[]){ /* debug main; does daytime on local host */ String str. Local. Host = ""; try{ str. Local. Host = Inet. Address. get. Local. Host(). get. Host. Name(); } catch (Unknown. Host. Exception e){ System. err. println ("Unable to find local host"); } Default. Socket. Client d = new Default. Socket. Client (str. Local. Host, i. DAYTIME_PORT); d. start(); } }// class Default. Socket. Client

Threaded Client Sockets To use this threaded client, we merely subclass it, override the

Threaded Client Sockets To use this threaded client, we merely subclass it, override the handle. Connection() method, and spawn off new instances. Default. Socket. Client start() Networked GUI Our Specific Socket Client (e. g. , web browser) View (Buttons, etc. )

Sending Mail We can use our Threaded Client to write a simple e-mail client.

Sending Mail We can use our Threaded Client to write a simple e-mail client. We won’t implement the user interface beyond a debug test main. (We could design a complex GUI, but won’t right now. ) Default. Socket. Client Mail. Socket -- Changes handle. Session() to match RFC mail requirements Quick. Mail (Sends a test message)

Sending Mail public class Mail. Socket extends Default. Socket. Client { String str. Message;

Sending Mail public class Mail. Socket extends Default. Socket. Client { String str. Message; String str. Recipient; String str. Sender; public Mail. Socket(String str. Server, String str. Sender, String str. Recipient, String str. Message){ super (str. Server, i. SMTP_PORT); this. str. Message = str. Message; this. str. Recipient = str. Recipient; this. str. Sender = str. Sender; } /* cont’d . . . Note that we could also have more constructor variables-subject line, etc. */

Sending Mail public void handle. Session(){ if (DEBUG) System. out. println("Sending mail"); send. Output("HELO

Sending Mail public void handle. Session(){ if (DEBUG) System. out. println("Sending mail"); send. Output("HELO from. Quick. Mailn"); /* Some servers verify this!!*/ send. Output("MAIL FROM: <" + str. Sender + ">n"); send. Output("RCPT TO: " + str. Recipient + "n"); send. Output("DATAn"); send. Output("Subject: Here's some mailn"); send. Output("From: Your Name <" + str. Sender + " >n"); send. Output("nn"); /* send the message */ send. Output(str. Message); send. Output("n. nn"); send. Output("QUITn"); if (DEBUG) System. out. println("Sent mail"); } }// class Mail. Socket

Sending Mail public class Quick. Mail { public static void main (String arg[]){ Mail.

Sending Mail public class Quick. Mail { public static void main (String arg[]){ Mail. Socket m. Sock = new Mail. Socket ("mail. mindspring. com", "david. dagon@mindspring. com", "Hi Dave, n Here’s some mail from GSMAS. n"); m. Sock. start(); } } // class Quick. Mail Note: I don’t mind getting e-mail from GSAMS participants; you might want to use your own e-mail address when testing.

URLs A URL specifies the location of networked resource--a file, for example. A common

URLs A URL specifies the location of networked resource--a file, for example. A common URL is one for a web resource: http: //www. javasoft. com Host Name -- the name of the machine ‘hosting’ the resource Other protocols are possible: ftp: // file: // jdbc: // Filename -- the pathname to the file on the host Port Number -- the port number to which to connect (optional). Reference -- a reference to a named anchor within a resource that usually identifies a specific location within a file (optional).

URLs The easiest way to create a URL in Java is to start with

URLs The easiest way to create a URL in Java is to start with a String: try{ URL my. URL = new URL (“http: //www. cc. gatech. edu”); } catch (Malformed. URLException e){ System. err. println (“This method: “ + e. to. String()); } URLs can also be created relative to an existing URL: try{ URL first. URL = new URL(“http: //www. foo. com/top_level”); URL second. URL = new URL (first. URL, “lower_level”); } catch (Exception e){; }

Using URLs contain many useful methods, including: get. Protocol(); returns the protocol identifier component

Using URLs contain many useful methods, including: get. Protocol(); returns the protocol identifier component of the URL (ftp/http, e. g. ). get. Host(); returns the host name component of the URL. get. Port(); returns the port number component of the URL (or -1 if not set). get. File(); returns the filename component of the URL. get. Ref(); returns the reference component of the URL.

import java. net. *; import java. io. *; public class URLReader. Example { public

import java. net. *; import java. io. *; public class URLReader. Example { public static void main (String[] args) throws Exception { if (args. length == 0) show. Usage(); URL my. URL = new URL("http: //” + args[0]); Buffered. Reader in = new Buffered. Reader(new Input. Stream. Reader (my. URL. open. Stream())); String str. Input; while ((str. Input = in. read. Line()) != null) System. out. println(str. Input); in. close(); } public static void show. Usage(){ System. err. println ("Usage: ntjava URLReader. Example <IP Address>"); System. exit(0); }//show. Usage }//URLReader. Example

Connecting to a URL One can also use “open. Connection()” to connect to a

Connecting to a URL One can also use “open. Connection()” to connect to a URL. This creates a communication link between your Java program and the URL over the network. For example: try { URL my. URL = new URL("http: //www. blarg. foo. org/"); my. URL. open. Connection(); } catch (Malformed. URLException e) { ; } catch (IOException e) { ; } One can then interact with the remote URL. (E. g. , POST information to web pages

Extracting the Stream from a URL import public java. net. *; java. io. *;

Extracting the Stream from a URL import public java. net. *; java. io. *; class URLConnection. Reader { static void main (String[] args) throws Exception { URL my. URL = new URL("http: //www. cc. gatech. edu/"); URLConnection uc = my. URL. open. Connection(); Buffered. Reader in = new Buffered. Reader (new Input. Stream. Reader (uc. get. Input. Stream())); /* see also get. Output. Stream() */ String input. Line; while ((input. Line = in. read. Line()) != null) System. out. println(input. Line); in. close(); } }

RMI: “Distributing the Object” Being a Analysis of Java’s Remote Method Invocation Capabilities

RMI: “Distributing the Object” Being a Analysis of Java’s Remote Method Invocation Capabilities

1. Motivation

1. Motivation

CORBA & RMI: Two Flavors of Alphabet Soup? Maybe you’ve heard of CORBA and/or

CORBA & RMI: Two Flavors of Alphabet Soup? Maybe you’ve heard of CORBA and/or RMI: the “new hot thing” in computing. GUI CORBA HTML OMG IDL Thin Clients (CGI) URL Java ORB (UDP) Foo (TCP/IP) Null Clients HORB (Non-type-safe Interaction) It’s hard to understand CORBA and RMI, in part because of all the confusing terms. . .

E H T Allows local invocation of operations on objects located anywhere on a

E H T Allows local invocation of operations on objects located anywhere on a network. S IC PURPOSE S The Common Object Request Broker Architecture defines a model of distributed computing. A DEFINED B What is CORBA?

E H T Allows local invocations of operations on objects located anywhere on a

E H T Allows local invocations of operations on objects located anywhere on a network. S IC PURPOSE S Java’s Remote Method Invocation defines a model of distributed computing. A DEFINED B What is RMI?

What’s the Difference? • • • CORBA supports multiple languages RMI is (relatively) easier

What’s the Difference? • • • CORBA supports multiple languages RMI is (relatively) easier to implement RMI allows optimization of protocols for communication CORBA separates interface definitions from implementation HORB, a variant of RMI, actually works in JDK 1. 02 (and therefore in most browsers without error). Here, we only add to the confusion with more terms. It might help to see an example of RMI.

2. “Hello RMI”

2. “Hello RMI”

A Contrived Experiment With RMI For this experiment, you will need: Two Java-ready Computers

A Contrived Experiment With RMI For this experiment, you will need: Two Java-ready Computers Two Fake Passports Three round trip tickets to Moscow 3, 500 Miles of CAT-5 wiring John Doe BOARDING PASS An MI 5 License to Thread

Experiment With RMI (Cont’d) 1. Hook one end of the CAT 5 cable to

Experiment With RMI (Cont’d) 1. Hook one end of the CAT 5 cable to a plane, and the other end to the first computer. 2. Fly to Moscow. 3. Blend in with the natives, and connect the cable to the second computer.

Experiment With RMI (Cont’d) 4. Return home. You now have a network. * RMI

Experiment With RMI (Cont’d) 4. Return home. You now have a network. * RMI lets us invoke methods that are found on the remote machine. So let’s write a little program. . . *(You may use a different networking configuration, if you’re short on cable. )

Program: Matryoshka Doll Server We will use this network to smuggle Matroyska dolls into

Program: Matryoshka Doll Server We will use this network to smuggle Matroyska dolls into the U. S. Our Moscow server will take in a doll, and return a new instance, encapsulating our original reference. Stubs Doll. Client public Matroyska. Doll get. Doll (Matroyska. Doll d); Moscovite Implementation Doll. Server public Matroyska. Doll get. Doll (Matroyska. Doll d) { // working code }

RMI Design Cycle Start Client Data Types policy Define Interface Implement Interface javac Implement

RMI Design Cycle Start Client Data Types policy Define Interface Implement Interface javac Implement Client Stub CLIENT Compile javac rmic Bind Objects Start Server policy Start RMI Registry Server class Server skeleton SERVER

1. Common Data Type public class Matryoska implements java. io. Serializable { private Matryoska

1. Common Data Type public class Matryoska implements java. io. Serializable { private Matryoska child; private String str. Microfilm; public Matryoska(String str. Microfilm, Matryoska child){ set. Child(child); set. Microfilm(str. Microfilm); This is merely } public void set. Microfilm (String str. Microfilm){ a linked list this. str. Microfilm = str. Microfilm; structure, but } it must support public void set. Child(Matryoska child){ serialization this. child = child; } public Matryoska get. Child(){ return child; } public String get. Microfilm(){ return str. Microfilm; } }// class Matryoska TOP SECRET:

2. Define The Interface import java. rmi. Remote; import java. rmi. Remote. Exception; public

2. Define The Interface import java. rmi. Remote; import java. rmi. Remote. Exception; public interface Doll. Design extends Remote { Matryoska get. Doll(Matryoska doll) throws Remote. Exception; } This means our object is Callable from any VM Communication failure or protocol problem occurs The java. rmi package: java. rmi. activation java. rmi. dgc java. rmi. registry java. rmi. server

3. Implement the Interface Or extend java. rmi. activation. Activatable (JDK 1. 2) import

3. Implement the Interface Or extend java. rmi. activation. Activatable (JDK 1. 2) import java. rmi. *; import java. rmi. server. *; import java. net. *; public class Doll. Implementation extends Unicast. Remote. Object implements Doll. Design { public Doll. Implementation() throws Remote. Exception { super(); } public Matryoska get. Doll(Matryoska doll) throws Remote. Exception { return new Matryoska (str. Message, doll); } public static String str. Message=”From Moscow With Stubs"; Causes object to be exported Convenience class; defines java. lang. Object methods to work with RMI (exports bytes, etc. ) calls Unicast. Remote. Object. export. Object()

3. Implement Interface (cont’d) public static void main (String arg[]) { if (System. get.

3. Implement Interface (cont’d) public static void main (String arg[]) { if (System. get. Security. Manager() == null) System. set. Security. Manager(new RMISecurity. Manager()); try { String name = "secret. Agent"; /* or “//host/secret. Agent” */ str. Message = Inet. Address. get. Local. Host(). get. Host. Name(); Doll. Design secret. Agent = new Doll. Implementation(); System. out. println ("Attempting to bind name: " + name); Naming. rebind(name, secret. Agent); System. out. println ("Mission accomplished. " + "nt. Operative: " + name + "bound on " + str. Message); } catch (Exception e) { System. err. println ("Nyet. "); System. err. println (e. get. Message()); Note the upcasting to e. print. Stack. Trace(); the interface from the } }//main implementation; this }//Doll. Implemenation exposes the stubs and not the object!

4. Compile (javac & rmic) Bash % % javac Matryoska. javac Doll. Implementation. java

4. Compile (javac & rmic) Bash % % javac Matryoska. javac Doll. Implementation. java rmic Doll. Implementation ls -l -rw-rw-r--rw-rw-r--rw-rw-r--rw-rw-r-- 1 1 1 1 boris boris 247 181 1757 1293 1729 3225 530 393 Apr Apr 12 12 14: 36 14: 20 14: 58 15: 28 14: 36 Bash% Skel == Server Stubs == Client Rmic is an RMI compiler for java. It’s in the soup. Doll. Design. class Doll. Design. java Doll. Implementation. class Doll. Implementation. java Doll. Implementation_Skel. class Doll. Implementation_Stub. class Matryoska. java

6. From Moscow With Stubs Note use of debugging listing of available objects import

6. From Moscow With Stubs Note use of debugging listing of available objects import java. rmi. *; import java. net. *; public class Doll. Client{ public static void main (String arg[]) { if (System. get. Security. Manager()==null) System. set. Security. Manager (new RMISecurity. Manager()); try { String name = "//" + arg[0] + "/secret. Agent"; String[] agents = Naming. list(name); for (int i=0; i<agents. length; i++) System. out. println ("t-->" + agents[i] + " found"); String local. Host = Inet. Address. get. Local. Host(). get. Host. Name(); Doll. Design secret. Agent = (Doll. Design) Naming. lookup(name); Matryoska doll = new Matryoska (local. Host, null); doll = secret. Agent. get. Doll(doll); System. out. println ("Done”); while (doll!=null){ System. out. println ("Doll-->" + doll. get. Microfilm()); doll=doll. get. Child(); } }//try

6. From Moscow With Stubs (cont’d) catch (Exception e){ System. err. println ("Error: "

6. From Moscow With Stubs (cont’d) catch (Exception e){ System. err. println ("Error: " + e. get. Message()); e. print. Stack. Trace(); } }//Main }//Doll. Client NOTE: We only create an instance of the interface, not the remote implementation Client must set a security manager as well; a similar policy must be invoked Remote resolution of stubs requires use of security manager

Smuggling Matryoska Dolls grant { permission java. net. Socket. Permission "*: 1024 -65535", “connect,

Smuggling Matryoska Dolls grant { permission java. net. Socket. Permission "*: 1024 -65535", “connect, accept"; permission java. net. Socket. Permission "*: 80", "connect"; }; 7. OK. Fly back to Moscow and make a file called “java. policy” Bash % rmiregistry & [5] Pid 4523 Bash % unset CLASSPATH Bash % java Djava. security. policy=java. policy Doll. Implementation & [6] Pid 4524 Set the policy Bash % file on startup with the -D option, or else!

8. Start The Client Bash % java -Djava. security. policy=java. policy Doll. Client 8.

8. Start The Client Bash % java -Djava. security. policy=java. policy Doll. Client 8. Fly home and create a similar policy file for the client. Start the service. Failure to start with the policy option will throw a security exception. This is new to JDK 1. 2

3. RMI Redux

3. RMI Redux

RMI Summary: Value RMI passes local objects by value--a copy gets sent. RMI passes

RMI Summary: Value RMI passes local objects by value--a copy gets sent. RMI passes remote objects by reference--not by copying. RMI stubs are proxies for the client to remote object (just like CORBA).

RMI Summary: Errors & GC Additional errors can be encountered; new exceptions must be

RMI Summary: Errors & GC Additional errors can be encountered; new exceptions must be addressed. RMI uses a reference counting gc; a zero count marks the distributed object as a weak reference. A “lease” is made on remote objects with a “dirty” call. Leases must be renewed or will expire. The java. rmi. server. Unreferenced interface allows objects to receive notification just prior to finalization. (Single method: unreferenced() ).

RMI Summary: Locate. Registry Default port: 1099 Class java. rmi. registry. Locate. Registry helps

RMI Summary: Locate. Registry Default port: 1099 Class java. rmi. registry. Locate. Registry helps locate remote registries: public static Registry get. Registry(); /* local */ public static Registry get. Registry (String host, int port); public static Registry get. Registry (String host); public static Registry create. Registry (int port);

java. rmi. Naming Class void bind(String name, Remote obj) throws Remote. Exception, Already. Bound.

java. rmi. Naming Class void bind(String name, Remote obj) throws Remote. Exception, Already. Bound. Exception, Access. Exception; Binds the specified name to a remote object. String[] list() throws Remote. Exception, Access. Exception; Returns an array of the names bound in the registry. Remote lookup(String name) throws Remote. Exception, Not. Bound. Exception, Access. Exception; Returns a reference, a stub, for the remote object associated with the specified name. void rebind(String name, Remote obj) Access. Exception; throws Remote. Exception, Rebinds the specified name to a new remote object. void unbind(String name) throws Not. Bound. Exception, Access. Exception; Remote. Exception, Destroys the binding for the specified name that is associated with a remote object.

RMI: Dynamic Stub Loading Dynamic stub loading is used where the client does not

RMI: Dynamic Stub Loading Dynamic stub loading is used where the client does not have local copies of the remote object. The stubs can even be generated on the fly. Lookup: 1) Local resolution attempted via CLASSPATH -- no security manager required 2) Server tells client the stub’s URL java. rmi. server. codebase -- can even be a third party Registry ! -- requires security manager

Java Native Invocation “Return of the Native Method”

Java Native Invocation “Return of the Native Method”

Native Methods--What? • Through Java Native Interface (JNI), Java supports the ability to call

Native Methods--What? • Through Java Native Interface (JNI), Java supports the ability to call native methods--shared object files written in languages such as C/C++ • The native keyword is used to identify methods that have implementation defined in such shared object files: public void native say. Hello(); JNI Java program Share Native object

Native Methods -- Why? • Before writing JNI, consider: – Could the program be

Native Methods -- Why? • Before writing JNI, consider: – Could the program be rewritten in/ported to Java? – It’s possible to write programs quickly in Java – What happens to portability? • JNI provides a means of providing cross-platform native code, but only if appropriate libraries are generated for each machine. (Code is portable, but not WORA--write once, run anywhere. )

JNI Generation--Overview Shared Object File (observe naming conventions) Java Source with native Java Class

JNI Generation--Overview Shared Object File (observe naming conventions) Java Source with native Java Class File (byte code) javah -jni compilatio n javac Java Source File loading library C/C++ Header #include JNI Implementation (C/C++ Code) Execution

Step 1: Organizing JNI vs. Java Functionality First, decide what code belongs with native

Step 1: Organizing JNI vs. Java Functionality First, decide what code belongs with native methods, and what is better left to Java. Consider: 1) JNI means loss of visibility modifiers (even private members can be discovered!) 2) JNI means manual garbage collection-difficult at times 3) JNI can imply a loss of OO control, unless native implementation is in C++, or a very OO-oriented set of C libraries.

public class Hello. World { public native void say. Hello(String str. Message); public void

public class Hello. World { public native void say. Hello(String str. Message); public void speak. Up() { System. out. println ("Java Says Hello, C"); say. Hello("C Says Hello, Java"); }// speak. Up() }// class Hello. World

Step 2: Generate Header File 1) Use javah tool from JDK to create header

Step 2: Generate Header File 1) Use javah tool from JDK to create header file. 2) Target your compiled class file. 3) Be sure to use the -jni switch: %javah -jni Hello. World 4) For older, non-JNI header files, use the -stub option with javah. (Ask: why are you using the old native invocation anyway? Consider upgrading to 1. 1) 5) Don’t edit the source Java file (e. g. , even adding a package statements invalidates the header file. ) This should create a header file essential for your implementation. . .

/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.

/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni. h> /* Header for class Hello. World */ #ifndef _Included_Hello. World #define _Included_Hello. World #ifdef __cplus extern "C" { #endif /* * Class: Hello. World * Method: say. Hello * Signature: (Ljava/lang/String; )V */ JNIEXPORT void JNICALL Java_Hello. World_say. Hello (JNIEnv *, jobject, jstring); #ifdef __cplus } #endif See the “Do Not Edit” Warning? Obey!

Step 3: Implement Your JNI Method 1) #include the header from javah 2) Use

Step 3: Implement Your JNI Method 1) #include the header from javah 2) Use the function prototypes generated by javah 3) Remember that Java Strings are objects, not char arrays. 4) Consult the JNI API for a list of helpful functions and methods 5) Note that ALL functions have two parameters, at least: JNIEnv * env, jobject this. Obj These are references to the VM and “this” object, respectively. They are the window into the process running in the VM.

#include <stdio. h> #include "Hello. World. h" JNIEXPORT void JNICALL Java_Hello. World_say. Hello (JNIEnv

#include <stdio. h> #include "Hello. World. h" JNIEXPORT void JNICALL Java_Hello. World_say. Hello (JNIEnv * env, jobject this. Obj, jstring str. Message){ const char *str = (*env)->Get. String. UTFChars(env, str. Message, 0); printf("%sn", str); (*env)->Release. String. UTFChars(env, str. Message, str); }// JNI method /*Note need to convert chars from Unicode to UTF, and then free created char buffer from the VM */

4. Compile the Object Observe the naming convention: lib<Share. Object>. so LINUX: %cc -I$JDK_HOME/include/genunix

4. Compile the Object Observe the naming convention: lib<Share. Object>. so LINUX: %cc -I$JDK_HOME/include/genunix -shared -o lib. Hello. so Hello. c SOLARIS: %cc -I$JDK_HOME/include/solaris -G -o lib. Hello. so Hello. c WINDOWS: Consider using a GNU port, or the upcoming batch file. . . ftp: //go. cygnus. com/pub/ftp. cygnus. com/ gnu-win 32/gnu-win 32 -b 18/cdk. exe

# # Makefile for Linux JNI Compilation # UPATH = /usr/bin/ JDK_PATH = /usr/local/jdk

# # Makefile for Linux JNI Compilation # UPATH = /usr/bin/ JDK_PATH = /usr/local/jdk 117_v 1 a/ # define utility programs and options CC = $(UPATH)cc CFLAGS = -I$(JDK_PATH)include/genunix -shared MAKE = $(UPATH)make CTAGS = $(UPATH)ctags For Solaris, INDENT = $(UPATH)indent -bl -c 41 -i 4 -l 72 -pcs change to # default target - builds Hello executable # /solaris Hello: Hello. c and -G $(CC) $(CFLAGS) -o lib. Hello. so Hello. c # "debug" target - builds executable with debug code # debug: Hello. c @CFLAGS="$(CFLAGS) -DDEBUG"; export CFLAGS; $(MAKE) -e # "pretty" target - beautify source files pretty: Hello. c ls $? | xargs -p -n 1 $(INDENT) @touch pretty # "clean" target - remove unwanted object files and executables clean: rm -f Hello. o pretty tags lint nohup. out a. out core

Windows Batch File @echo Batch File for JNI W 95 Dev. Studio 5 @echo

Windows Batch File @echo Batch File for JNI W 95 Dev. Studio 5 @echo Making clean @del *. obj @del *. lib @del *. dll @del *. pch @del *. pdb @del *. exp @del *. idb @echo Compiling all C files from this directory. . . @cl -I%JDKPATH%includewin 32 /nologo /MTd /W 4 /Gm /GX /Zi /Od /D "WIN 32" /D "_DEBUG" /D "_WINDOWS" /YX /c /LD *. c @echo linking. . . @link /nologo /subsystem: windows /dll /incremental: no /machine: I 386 /out: %1. dll *. obj

5. Load the Library public class Test{ static { /* * Our library is

5. Load the Library public class Test{ static { /* * Our library is in a file called "lib. Hello. so", but * just pass in "Hello" since Java will prepend "lib" * and append the ". so" extension. Windows users * should omit the “. dll” extension as well. */ System. load. Library("Hello"); }// static load public static void main (String arg[]) { Hello. World hw = new Hello. World(); hw. speak. Up(); } // main }// class Test

6. Execute 1) Make sure the library is in the path of the environment

6. Execute 1) Make sure the library is in the path of the environment variable: LD_LIBRARY_PATH 2) For your shell, you can set: LD_LIBRARY_PATH=. /: $LD_LIBRARY_PATH 3) Windows users need to set the PATH appropriately: PATH=%PATH%; c: My. Library

7. DEBUG (and repeat. . . ) Numerous problems may come up during compilation.

7. DEBUG (and repeat. . . ) Numerous problems may come up during compilation. Resources for debugging JNI problems: http: //www. codeguru. com/java/JNI/index. shtml http: //www. mindspring. com/~david. dagon/jni/Native. txt

Concluding Thoughts Thank you for your patience, and very constructive suggestions! I’ve enjoyed working

Concluding Thoughts Thank you for your patience, and very constructive suggestions! I’ve enjoyed working on this lecture series. If you’re ever called upon to deliver a satellite lecture, may I offer some of my experiences? Lessons learned: -- GSAMS lectures are a different beast. -- Two-way connectivity is present, but needs to be facilitated. -- Lecture materials need can develop contextual dependencies that make them unsuitable/irrelevant for wider audiences. -- Provide supplemental feedback mechanisms: the “television” effect seems to limit some types of discussion, and encourage others. -- The lecture ends when the network goes down.