|
|
Computer networks are the biggest Big New Thing for decades. They are now of central importance to all information technology. With the recent explosive growth of the internet, they are rapidly "she" becoming of crucial importance to all of modern society.
The World Wide Web is the Big New Thing in computer networking.
History:
Through 1991 and 1993, Tim Berners Lee continued working on the design of the Web, coordinating feedback from users across the Internet. His initial specifications of URIs, HTTP and HTML were refined and discussed in larger circles as the Web technology spread.
See also: Tim Berners-Lee.
A browser, or viewer program is used to fetch and display "pages" of information from a server. A page is simply an ASCII text file, written using a simple markup language called Hypertext Meta Language (HTML). You may find an introduction here.
The URL is the basis of the WWW. Think of a URL as an address that can lead you to any file on any machine anywhere in the world. Unlike the common postal address, however, these are written backwards. (Actually backwards makes more sense. My postal adddress was:
HP Bischof 3002 ST RT 48 Oswego, 13126 NY, USA.
But if you want to deliver a letter to me, shouldn't you first go to the USA, then NY, then Oswego, then 3002 ST RT 48, then to HP Bischof? The URL is written in that more logical order.)
A URL defines the location of a WWW page in the following way:
service:host:port/file and resource details
For example:
URLs on the Web don't have to use the HTTP protocol. Some other URLs you might encounter are:
To fetch a WWW page, the browser application process running on your local computer first establishes a connection to the remote host.
What this means is that the browser process uses the facilities of the network connecting the two computers to send a "connection request" message to a server process running on the computer whose name was given in the URL.
If the remote server process is prepared to accept the connection, it responds with a "connection accepted" message.
Note that we are, for the moment, ignoring the process of "looking up" the remote host - discovering the network address associated with its domain name.
Once the two application processes have an established connection between them, they can communicate reliably.
The browser then sends a request, in ordinary plain text, to the server, thus:
GET /home.html
The string GET something is one of many commands defined in the Hypertext Transfer Protocol, HTTP. The server responds by returning the contents of a file.
Finally, the browser process interprets the HTML markup in the returned file, and displays it to the user.
The Internet (short for internetworking, the practice of linking technologically different and independently operated networks), is a network of networks which allows users to communicate using electronic mail, to retrieve data stored in databases, and to access distant computers. The "core" of Internet includes the National Science Foundation's NSFNET, the Department of Energy's Energy Science Network (ESnet), the NASA Science Internet (NSI) as well as Defense's ARPANET and Terrestrial Wideband Network (TWBnet). Internet also includes a larger, and continually expanding, collection of interconnected regional, campus, and other networks throughout the U.S. and overseas, as well as several networks that provide service on a for-profit basis.
These linked networks are independently operated; there is no central control of Internet. Internet began as an Advanced Research Projects Agency research project to investigate computer networking technology. The networks that comprise the National Research and Education Network (NREN), a component of the High Performance Computing and Communications Program, are a part of the current Internet.
Copied from: www.onelook.com.
A local area network which may not be connected to the Internet, but which has some similar functions. Some organizations set up World Wide Web servers on their own internal networks so employees have access to the organization's Web document Copied from: www.onelook.com.
(From: An Internet Encyclopedia) Douglas Comer defines a protocol as "a formal description of message formats and the rules two or more machines must follow to exchange those messages."
Protocols usually exist in two forms. First, they exist in a textual form for humans to understand. Second, they exist as programming code for computers to understand. Both forms should ultimately specify the precise interpretation of every bit of every message exchanged across a network.
Protocols exist at every point where logical program flow crosses between hosts. In other words, we need protocols every time we want to do something on another computer. Every time we want to print something on a network printer we need protocols. Every time we want to download a file we need protocols. Every time we want to save our work on disk, we don't need protocols - unless the disk is on a network file server.
Usually multiple protocols will be in use simultaneously. For one thing, computers usually do several things at once, and often for several people at once. Therefore, most protocols support multitasking. Also, one operation can involve several protocols. For example, consider the NFS (Network File System) protocol. A write to a file is done with an NFS operation, that uses another protocol (RPC) to perform a function call on a remote host, that uses another protocol (UDP) to deliver a datagram to a port on a remote host, that uses another protocol to deliver a datagram on an Ethernet, and so on. Along the way we made need to lookup host names (using the DNS protocol), convert data to a network standard form (using the XDR protocol), find a routing path to the host (using one or many of numerous protocols) - I think you get the idea.
Protocol layering is a common technique to simplify networking designs by dividing them into functional layers, and assigning protocols to perform each layer's task.
For example, it is common to separate the functions of data delivery and connection management into separate layers, and therefore separate protocols. Thus, one protocol is designed to perform data delivery, and another protocol, layered above the first, performs connection management. The data delivery protocol is fairly simple and knows nothing of connection management. The connection management protocol is also fairly simple, since it doesn't need to concern itself with data delivery.
Protocol layering produces simple protocols, each with a few well-defined tasks. These protocols can then be assembled into a useful whole. Individual protocols can also be removed or replaced.
The most important layered protocol designs are the Internet's original DoD model, and the OSI Seven Layer Model. The modern Internet represents a fusion of both models.
(From: An Internet Encyclopedia) In the 1980s, the European-dominated International Standards Organization (ISO), began to develop its Open Systems Interconnection (OSI) networking suite. OSI has two major components: an abstract model of networking (the Basic Reference Model, or -- seven-layer model --), and a set of concrete protocols. The standard documents that describe OSI are for sale and not currently available online.
Parts of OSI have influenced Internet protocol development, but none more than the abstract model itself, documented in OSI 7498 and its various addenda. In this model, a networking system is divided into layers. Within each layer, one or more entities implement its functionality. Each entity interacts directly only with the layer immediately beneath it, and provides facilities for use by the layer above it. Protocols enable an entity in one host to interact with a corresponding entity at the same layer in a remote host.
The seven layers of the OSI Basic Reference Model are (from bottom to top):
The original Internet protocol specifications defined a four-level model, and protocols designed around it (like TCP) have difficulty fitting neatly into the seven-layer model. Most newer designs use the seven-layer model.
TCP/IP is the essential two-layer program that each Internet point-of-presence (POP) or SLIP/PPP user must use.
The Transmission Control Protocol (a protocol is a formal set of rules for communicating) manages the packaging of data into the packets that get routed on different paths over the Internet and reassembled at their destination.
The Internet Protocol handles the address part of each data packet so that it is routed to the right destination.
TCP/IP can be used on many data-link layers (can support many network hardware implementations).
These two protocols are the most important, TCP/IP is really a suite of protocols. (Some of these are viewed as alternative protocols and others as application protocols.) The ones you are most likely to use (directly or indirectly) are: HTTP, FTP, Telnet, Gopher, PPP, and SMTP.
Related protocols, some of them may be included in a TCP/IP package:
TCP/IP is normally considered to be a 4 layer system:
The function of the TCP protocol, is to provide a:
reliable all data is delivered correctly
connection-oriented the protocol provides procedures for establishing
interprocess connections.
byte stream ie, no visible packetisation so far as the application
processes are concerned
end-to-end
... interprocess communication service.
The User Datagram Protocol provides a connectionless alternative transport service to TCP for applications where reliable stream service is not needed. UDP datagrams can be dropped, duplicated or delivered out of order, same as for IP.
· telnet for remote login · ftp the file transfer protocol · SMTP simple mail transfer protocol · SNMP simple network management protocol
An example:
Every Internet-connected system has a unique Internet host address.
This is a 32 bit, or 4 byte, binary number.
Internet addresses are written as a dotted sequence of the form:
a.b.c.d
where a, b, c and d etc, are the decimal values (ranging from 0 to 255) of the 4 bytes which make up the internet address, for example:
129.3.20.4
129.3.20.4 is the IP address of ilon,or to use its full name
ilon.cs.oswego.edu
We will later see how the name of a computer is mapped to its IP-address.
An IP-address only makes sense to the TCP/IP suite. A data link such as an Ethernet or a token ring has its own addressing scheme (often 48 bits).
The-byte address is often used, which is divided into a 3-byte vendor ID and a 3-byte vendor-defined field. Ethernet manufacturers are assigned a unique vendor ID, and are then responsible for insuring that all of their devices have unique addresses in the last 3 bytes.
A network, such as an Ethernet can be used by different network layers at the same time. See also RFC 802.
When an application sends data using TCP is sent down the protocol stack.
A pyhsical proporty of an Ethernetframe is, that the size of its data must be between 46 and 1500 bytes.
TCP is using protocl port numbers to indentify the ultimate destination.
How does one deteremine the port to communicate with?
Two popular Application Programming Interface using TCP/IP protocols are called sockets and TLI (transport layer interface).
A socket is one end-point of a two-way communication link between two programs running on the network. Socket classes are used to represent the connection between a client program and a server program. The java.net package provides two classes--Socket and ServerSocket--that implement the client side of the connection and the server side of the connection, respectively.
A socket is a network communications endpoint.
A socket is an object from which messages are sent and received.
Socket operations resemble file operations in many respects:
See also: java.net
Through the classes in java.net, Java programs can use TCP or UDP to communicate over the Internet. The URL, URLConnection, Socket, and ServerSocket classes all use TCP to communicate over the network. The DatagramPacket, DatagramSocket, and MulticastSocket classes are for use with UDP.
Host info
import java.net.*;
import java.io.*;
import java.util.*;
public class HostInfo {
public static void main(String argv[]) {
InetAddress ipAddr;
try {
ipAddr = InetAddress.getLocalHost();
System.out.println ("This is "+ipAddr);
} catch (UnknownHostException e) {
System.out.println ("Unknown host");
}
}
}
Source Code: Src/16/HostInfo.java
% java HostInfo This is yps/129.21.38.198
import java.net.*;
import java.io.*;
import java.util.*;
public class DayTime {
String hostName = "yps";
int port = 13;
private void printMessage() {
System.out.println("-h ----> help");
System.out.println("[-host hostName]");
System.out.println("[-port port]");
}
/**
* Parse the commandlind arguments and sets variables.
*/
public void parseArgs(String args[]) {
for (int i = 0; i < args.length; i ++) {
if (args[i].equals("-h"))
printMessage();
else if (args[i].equals("-host"))
hostName = args[++i];
else if (args[i].equals("-port"))
port = new Integer(args[++i]).intValue();
}
}
public void doTheJob() {
try {
System.out.println("host: " + hostName );
System.out.println("port: " + port );
Socket sock = new Socket(hostName, port);
BufferedReader din = new BufferedReader (
new InputStreamReader (sock.getInputStream()));
String rTime = din.readLine ();
System.out.println (rTime);
sock.close();
} catch (Exception e) {
System.out.println (e);
}
}
public static void main(String argv[]) {
DayTime aDayTime = new DayTime();
aDayTime.parseArgs(argv);
aDayTime.doTheJob();
}
}
Source Code: Src/16/DayTime.java
% java DayTime host: yps port: 13 Mon Oct 24 09:05:49 EDT 2005
import java.net.*;
import java.io.*;
import java.util.*;
public class DayTimeServer extends Thread {
ServerSocket listen;
int port = 4242;
public DayTimeServer() {
}
public DayTimeServer(int port) {
try {
listen = new ServerSocket(port);
System.out.println ("2: Listening on port: "
+ listen.getLocalPort());
} catch(Exception e) {
System.out.println(e);
}
}
private void printMessage() {
System.out.println("-h ----> help");
System.out.println(" -port port");
System.out.println(" {-port port}");
System.out.println("or ");
System.out.println(" no argument");
}
/**
* Parse the commandlind arguments and sets variables.
*/
private void parseArgs(String args[]) {
for (int i = 0; i < args.length; i ++) {
if (args[i].equals("-h"))
printMessage();
else if (args[i].equals("-port")) {
port = new Integer(args[++i]).intValue();
new DayTimeServer(port).start();
}
}
}
public void run() {
try {
for(;;) {
Socket clnt = listen.accept();
System.out.println(clnt.toString());
PrintWriter out = new PrintWriter
(clnt.getOutputStream (), true);
out.println("It is now: " + new Date());
clnt.close();
}
} catch(Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
public static void main(String argv[]) {
if ( argv.length == 0 )
new DayTimeServer(0).start();
else
new DayTimeServer().parseArgs(argv);
}
}
Source Code: Src/16/DayTimeServer.java
% # Window 1 java DayTimeServer Socket[addr=/129.21.36.168,port=63941,localport=63931] Socket[addr=/129.21.36.168,port=63950,localport=63931] ... % # Window 2 % telnet yps.cs.rit.edu 63931 Trying 129.21.36.168... Connected to yps. Escape character is '^]'. Mon Oct 24 09:05:51 EDT 2005 Connection to yps closed by foreign host. % java DayTime host: holly.cs.rit.edu port: 13 Mon Oct 24 09:05:52 EDT 2005 % java DayTime -host yps host: yps port: 13 java.net.ConnectException: Connection refused % java DayTime -host yps -port 63931 host: yps port: 63931 Mon Oct 24 09:05:54 EDT 2005 %
import java.io.*;
import java.net.*;
class HpEchoSocketTest {
Socket s;
String hostname;
int port;
PrintWriter out = null;
BufferedReader in = null;
public void readAndPrint() throws Exception {
InputStream ins;
OutputStream os;
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
stdIn.close();
}
///////////////////////////////////////////////
public HpEchoSocketTest(String name, int port) {
hostname = name;
this.port = port;
try {
s = new Socket(hostname, port);
out = new PrintWriter(
s.getOutputStream(), true);
in = new BufferedReader(
new InputStreamReader(
s.getInputStream()));
readAndPrint();
in.close();
out.close();
} catch (Exception e ) {
System.out.println(e.toString());
System.exit(1);
}
}
public static void main(String[] args) {
HpEchoSocketTest st;
String host = "holly";
int port = 7;
st = new HpEchoSocketTest(host, port);
}
}
Source Code: Src/16/HpEchoSocketTest.java
This client program is straightforward and simple because the Echo server implements a simple protocol. The client sends text to the server, and the server echoes it back.
These are the typical steps:
Class URL represents a Uniform Resource Locator, a pointer to a "resource" on the World Wide Web. A resource can be something as simple as a file or a directory, or it can be a reference to a more complicated object, such as a query to a database or to a search engine. More information on the types of URLs and their formats can be found at: http://www.ncsa.uiuc.edu/demoweb/url-primer.html
import java.io.*;
import java.net.URL;
import java.net.MalformedURLException;
public class Url_Read {
public static void readFromUrl(String theUrl) {
URL aUrl = null;
BufferedReader in = null;
String line;
try {
aUrl = new URL(theUrl);
System.out.println("getPort() " + aUrl.getPort());
System.out.println("getHost() " + aUrl.getHost());
System.out.println("getProtocol() " + aUrl.getProtocol());
System.out.println("getFile() " + aUrl.getFile());
System.out.println("getRef() " + aUrl.getRef());
in = new BufferedReader(
new InputStreamReader( aUrl.openStream() ) );
while ( ( line = in.readLine() ) != null ) {
System.out.println(line);
}
in.close();
} catch (MalformedURLException e) {
System.err.println("Something is wrong with this " +
theUrl + ".");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: "
+ theUrl );
System.exit(1);
}
}
public static void main( String args[] ) {
if ( args.length != 1 ) {
System.err.println(
"Usage: java Url_Read url");
System.exit(1);
}
try {
readFromUrl(args[0]);
}
catch ( NumberFormatException e) {
System.out.println(args[0] + " is not a number ;-(");
}
}
}
Source Code: Src/16/Url_Read.java
% java Url_Read http://www.cs.rit.edu/~hpb | sed 15q getPort() -1 getHost() www.cs.rit.edu getProtocol() http getFile() /~hpb getRef() null <HTML> <HEAD> <title>Hans-Peter Bischof's Home Page</title> </HEAD> <FRAMESET cols="230,*"> <frame name="toc" TARGET="_main" src="toc.html" scrolling="auto"> <frame name="intro" src="intro.html" scrolling="auto">
import java.net.*;
import java.io.*;
import java.util.*;
public class MTS extends Thread {
ServerSocket listen;
static String hostName = "yps";
int port = 4242;
int id = 0;
public MTS() {
listen = null;
}
public MTS(int port) {
try {
listen = new ServerSocket(port);
System.out.println ("Listening on port: "
+ getLocalPort());
} catch(Exception e) {
System.out.println(e);
}
}
public MTS(int port, int id) {
this(port);
this.id = id;
}
public int getLocalPort () {
return listen.getLocalPort();
}
private void printMessage() {
System.out.println("-h ----> help");
System.out.println("[-host hostName");
System.out.println(" -port port");
System.out.println(" {-port port}");
System.out.println("or ");
System.out.println(" no argument");
}
/**
* Parse the commandlind arguments and sets variables.
*/
public void parseArgs(String args[]) {
for (int i = 0; i < args.length; i ++) {
if (args[i].equals("-h"))
printMessage();
else if (args[i].equals("-host"))
hostName = args[++i];
else if (args[i].equals("-port")) {
port = new Integer(args[++i]).intValue();
new MTS(port).listenToPort();
}
}
}
public void run() {
try {
Socket clnt = listen.accept();
System.out.println(clnt.toString());
PrintWriter out = new PrintWriter
(clnt.getOutputStream (), true);
out.println("It is now: " + new Date());
System.out.println(id + " .... falling asleep");
sleep(1000);
System.out.println("\t" + id + " .... wake up");
listen.close();
} catch(Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
public void listenToPort() {
try {
int id = 0;
for(;;) {
Socket clnt = listen.accept();
int newSocket;
System.out.println("Somebody connected ... ");
MTS aServer = new MTS(0, id++);
aServer.start();
System.out.println("offer ... " +
aServer.getLocalPort());
PrintWriter out = new PrintWriter
(clnt.getOutputStream (), true);
out.println(aServer.getLocalPort());
// clnt.close();
}
} catch(Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
public static void main(String argv[]) {
if ( argv.length == 0 )
new MTS(0).listenToPort();
else
new MTS().parseArgs(argv);
}
}
Source Code: Src/16/MTS.java
import java.net.*;
import java.io.*;
import java.util.*;
public class MTSclient {
String hostName = "yps";
int port = 13;
private void printMessage() {
System.out.println("-h ----> help");
System.out.println("[-host hostName]");
System.out.println("[-port port]");
}
/**
* Parse the commandlind arguments and sets variables.
*/
public void parseArgs(String args[]) {
for (int i = 0; i < args.length; i ++) {
if (args[i].equals("-h"))
printMessage();
else if (args[i].equals("-host"))
hostName = args[++i];
else if (args[i].equals("-port"))
port = new Integer(args[++i]).intValue();
}
}
public void doTheJob() {
try {
Socket socket = new Socket(hostName, port);
BufferedReader din = new BufferedReader (
new InputStreamReader (socket.getInputStream()));
String newPort = din.readLine ();
System.out.println ("Use from now in port: " + newPort);
socket.close();
din.close();
socket = new Socket(hostName,
new Integer(newPort).intValue());
din = new BufferedReader (
new InputStreamReader (socket.getInputStream()));
System.out.println("got: " + din.readLine () );
} catch (Exception e) {
System.out.println (e);
}
}
public static void main(String argv[]) {
MTSclient aMTSclient = new MTSclient();
aMTSclient.parseArgs(argv);
aMTSclient.doTheJob();
}
}
Source Code: Src/16/MTSclient.java
# Window 1: % java MTS Listening on port: 1234 Somebody connected ... local port: 53064 Sleep for a while # Window 2: java MTSclient -port 1234 & [1] 6500 yps 7 142 local port: 1234 Mon Oct 24 09:05:55 EDT 2005
An example:
import java.net.*;
import java.io.*;
import java.util.*;
public class DayTimeUDPServer extends Thread {
DatagramSocket socket;
static String hostName = "yps";
int port = 4242;
public DayTimeUDPServer() {
}
public DayTimeUDPServer(int port) {
try {
socket = new DatagramSocket(port);
System.out.println ("Listening on port: "
+ socket.getLocalPort());
} catch(Exception e) {
System.out.println(e);
}
}
private void printMessage() {
System.out.println("-h ----> help");
System.out.println("[-host hostName");
System.out.println(" -port port");
System.out.println(" {-port port}");
System.out.println("or ");
System.out.println(" no argument");
}
/**
* Parse the commandlind arguments and sets variables.
*/
public void parseArgs(String args[]) {
for (int i = 0; i < args.length; i ++) {
if (args[i].equals("-h"))
printMessage();
else if (args[i].equals("-host"))
hostName = args[++i];
else if (args[i].equals("-port")) {
port = new Integer(args[++i]).intValue();
new DayTimeUDPServer(port).start();
}
}
}
public void run() {
byte[] buf = new byte[256];
try {
for(;;) {
String sendThis = "es schlaegt: " + new Date();
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
InetAddress address = packet.getAddress();
int port = packet.getPort();
buf = sendThis.getBytes();
packet = new DatagramPacket(buf, buf.length, address, port);
System.out.println("Sending to port: " + port );
System.out.println("Sending data: " + new String(buf) );
socket.send(packet);
}
} catch(Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
public static void main(String argv[]) {
if ( argv.length == 0 )
new DayTimeUDPServer(0).start();
else
new DayTimeUDPServer().parseArgs(argv);
}
}
Source Code: Src/16/DayTimeUDPServer.java
import java.net.*;
import java.io.*;
import java.util.*;
public class DayTimeUDP {
String hostName = "yps";
int port = 13;
private void printMessage() {
System.out.println("-h ----> help");
System.out.println("[-host hostName]");
System.out.println("[-port port]");
}
/**
* Parse the commandlind arguments and sets variables.
*/
public void parseArgs(String args[]) {
for (int i = 0; i < args.length; i ++) {
if (args[i].equals("-h"))
printMessage();
else if (args[i].equals("-host"))
hostName = args[++i];
else if (args[i].equals("-port"))
port = new Integer(args[++i]).intValue();
}
}
public void doTheJob() {
try {
byte buf[] = new byte[64];
InetAddress aInetAddress = InetAddress.getByName(hostName);
DatagramPacket dp = new DatagramPacket(buf, buf.length);
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(buf,
buf.length, aInetAddress, port);
socket.send(packet);
System.out.println("host: " + hostName );
System.out.println("port: " + port );
System.out.println("after creation");
socket.receive(dp);
System.out.println("received: -" +
new String(dp.getData() ) + "-" );
socket.close();
} catch (Exception e) {
System.out.println (e);
e.printStackTrace();
}
}
public static void main(String argv[]) {
DayTimeUDP aDayTimeUDP = new DayTimeUDP();
aDayTimeUDP.parseArgs(argv);
aDayTimeUDP.doTheJob();
}
}
Source Code: Src/16/DayTimeUDP.java
# Window 1: % java DayTimeUDPServer -port 53818 Listening on port: 53818 Sending to port: 53840 Mon Oct 24 09:05:56 EDT 2005 # Window 2: % java DayTimeUDP -port 53818 host: yps port: 53818 after creation received: -es schlaegt: Mon Oct 24 09:05:56 EDT 2005
See also http://java.sun.com/docs/books/tutorial/rmi.
Part of the text and programs are from there. Copyright belongs to Ann Wollrath and Jim Waldo.
See also http://java.sun.com/products/jdk/1.2/docs/guide/rmi/.
The Java Remote Method Invocation (RMI) system allows an object running in one Java Virtual Machine (VM) to invoke methods on an object running in another Java VM. RMI provides for remote communication between programs written in the Java programming language.
The illustration below depicts an RMI distributed application that uses the registry to obtain references to a remote object. The server calls the registry to associate a name with a remote object. The client looks up the remote object by its name in the server's registry and then invokes a method on it.
The problem is: you need a reference of an object, before you can send a method to it.
....
private static final long INTERFACE_ID = 32;
private final long m2mic__String__METHOD_1 = 0;
...
public void knockKnock( String _0) {
try {
ByteArrayOutputStream aS = new ByteArrayOutputStream(1024);
ObjectOutputStream p = new ObjectOutputStream(aS);
p.writeObject(_0);
p.close();
RmiPacket aRmiPacket = new RmiPacket( INTERFACE_ID,
m2mic__String__METHOD_1,
aS.toByteArray() );
netWorkCommEndPoint.sendDataToMany(aRmiPacket);
e.printStackTrace();
System.exit(1);
}
}
....
private static final long INTERFACE_ID = 32;
private final long m2mic__String__METHOD_1 = 0;
RmiPacket aRmiPacket = null;
aRmiPacket = aM2mCommEndPoint.readData();
theData = aRmiPacket.getData();
if ( aRmiPacket.getMethodId() == m2mic__String__METHOD_1) {
String __0 = (String)ip.readObject();
aThisClass.knockKnock(__0);
}
...
rmic generates the Sender and ReceiverProxys.
Where does the sender proxy come from?
A non-remote object, that is passed as a parameter of a remote method invocation or returned as a result of a remote method invocation, is passed by copy; that is, the object is serialized using the Java Object Serialization mechanism.
So, when a non-remote object is passed as an argument or return value in a remote method invocation, the content of the non-remote object is copied before invoking the call on the remote object.
When a non-remote object is returned from a remote method invocation, a new object is created in the calling virtual machine
RMI has been enhanced in the following areas:
Stolen from: http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html#rmi
This is a two-step process. In the first step you use the javac compiler to compile the source files, which contain the implementation of the remote interfaces and implementations, the server classes, and the client classes. In the second step you use the rmic compiler to create stubs for the remote objects. RMI uses a remote object's stub class as a proxy in clients so that clients can communicate with a particular remote object.
In this step you make everything--the class files associated with the remote interfaces, stubs, and other classes that need to be downloaded to clients.
Starting the application includes running the RMI remote object registry, the server, and the client.
We have to design a protocol that allows jobs to be submitted to the server and results of the job to be returned to the client. This protocol is expressed in interfaces supported by the server and by the objects that are submitted to the sever, as shown in the following figure.
The Client:
import java.rmi.*;
public class HelloC {
public static void main(String args[] ) {
String message = "";
try {
HelloInterface obj = (HelloInterface)Naming.
lookup("//aragorn/IamAhelloImplementationObject");
message = obj.sayHello();
System.out.println(message);
} catch (Exception e) {
System.out.println("HelloC exception: " +
e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_D/HelloC.java The interface:
public interface HelloInterface extends java.rmi.Remote {
String sayHello() throws java.rmi.RemoteException;
}
Source Code: Src/16_D/HelloInterface.java
The implementation of the interface:
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class HelloImplementation
extends UnicastRemoteObject
implements HelloInterface {
public HelloImplementation() throws RemoteException {
}
public String sayHello() throws RemoteException {
return "Hello World my friend.";
}
}
Source Code: Src/16_D/HelloImplementation.java
The implementation of the server:
import java.rmi.*;
public class HelloServer {
public static void main(String args[])
{
// System.setSecurityManager(new RMISecurityManager());
try {
HelloInterface obj = new HelloImplementation();
Naming.rebind("//aragorn/IamAhelloImplementationObject", obj);
System.out.println("HelloServer bound in registry");
} catch (Exception e) {
System.out.println("HelloImpl err: " + e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_D/HelloServer.java
The RMISecurityManager class defines a default security policy for RMI applications (not applets). For code loaded from a class loader, the security manager disables all functions except class definition and access. This class may be subclassed to implement a different policy. To set a RMISecurityManager, add the following to an application's main() method:
System.setSecurityManager(new RMISecurityManager());
If no security manager has been set, RMI will only load classes from local system files as defined by CLASSPATH.
is the bootstrap mechanism for obtaining references to remote objects based on Uniform Resource Locator (URL) syntax. The URL for a remote object is specified using the usual host, port and name:
rmi://host:port/name host = host
name of registry (defaults to the current host) port = port
number of registry (defaults to the registry port number) name = name
for remote object
The makefile:
1 2 all: 3 rmic HelloImpl 4 rmiregistry & 5 sleep 1 6 javac HelloImpl.java 7 java HelloImpl & 8 sleep 4 9 javac HelloC.java 10 java HelloC 11
Source Code: Src/16_D/Makefile
% make -f Makefile rmic HelloImpl rmiregistry & javac HelloImpl.java java HelloImpl & sleep 4 HelloServer bound in registry javac HelloC.java java HelloC Hello World my friend.
Note: Make sure that rmiregistry is dead before you log out!
Note: Make sure that every java server is dead before you log out!
1 #!/bin/sh
2
3 TO_FIND="registry"
4 if [ $# -eq 1 ]
5 then
6 if [ $1 -eq "java" ]
7 then
8 TO_FIND="java"
9 fi
10 fi
11
12
13 ps -edf | \
14 grep $TO_FIND | \
15 grep -v grep | \
16 grep -v kill | \
17 grep -v vi | \
18 awk ' { print $2 }' | \
19 while read x
20 do
21 echo "kill -9 $x"
22 kill -9 $x 2> /dev/null
23 done
24
25 exit 0
Source Code: Src/16_D/killIt
% ps -edf | grep java
The improved makefile:
Source Code: Src/16_D/makefile
% make
rmic HelloImpl
javac HelloC.java
rmiregistry &
sleep 1
java HelloImpl &
sleep 4
HelloImpl: HelloImpl(String s)
HelloServer bound in registry
java HelloC
Hello World my friend.
killIt java
kill -9 26491
kill -9 26489
kill -9 26438
kill -9 26332
kill -9 26501
Killed
killIt
Killed
The registry by default runs on port 1099. To start the registry on a different port, specify the port number in the command. For example, to start the registry on port 2001:
% rmiregistry 2001
For example, if the registry is running on port 2001 in the Hello World example, here is the call required to bind HelloServer to the remote object reference:
Naming.lookup("//yps:2001/HelloServer", obj);
The Client:
import java.rmi.*;
public class HelloC {
public static void main(String args[] ) {
String message = "";
try {
Hello obj =
(Hello)Naming.lookup("//yps:2001/HelloServer");
message = obj.sayHello();
System.out.println(message);
} catch (Exception e) {
System.out.println("Something went wrong: " +
e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_P/HelloC.java
The Server:
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class HelloImpl
extends UnicastRemoteObject
implements Hello
{
private String name;
public HelloImpl(String s) throws RemoteException {
name = s;
}
public String sayHello() throws RemoteException {
return "Stanley Kubrick was there!";
}
public static void main(String args[])
{
// Create and install a security manager
// System.setSecurityManager(new RMISecurityManager());
try {
HelloImpl obj = new HelloImpl("HelloServer");
Naming.rebind("//yps:2001/HelloServer", obj);
System.out.println("HelloServer bound in registry");
} catch (Exception e) {
System.out.println("HelloImpl err: " + e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_P/HelloImpl.java
The interface:
public interface Hello extends java.rmi.Remote {
String sayHello() throws java.rmi.RemoteException;
}
Source Code: Src/16_P/Hello.java
The makefile:
1 2 3 all: Hello.class HelloC.class HelloImpl.class \ 4 HelloImpl_Skel.class HelloImpl_Stub.class 5 6 rmiregistry 2001 & 7 sleep 1 8 java HelloImpl & 9 sleep 4 10 java HelloC 11 killIt java 12 killIt 13 14 15 HelloImpl_Skel.class HelloImpl_Stub.class: HelloImpl.java 16 rmic HelloImpl 17 18 Hello.class: Hello.java 19 javac Hello.java 20 21 HelloC.class: HelloC.java 22 javac HelloC.java 23 24 HelloImpl.class: HelloImpl.java 25 javac HelloImpl.java 26 27 clean: 28 rm -f *class
Source Code: Src/16_P/makefile
Client:
import java.rmi.*;
public class Client {
public static void main(String args[] ) {
String message = "";
try {
MyServer obj =
(MyServer)Naming.lookup("//yps:2001/Server1");
message = obj.sayHello();
System.out.println(message);
obj = (MyServer)Naming.lookup("//yps:2001/Server2");
message = obj.sayHello();
System.out.println(message);
} catch (Exception e) {
System.out.println("Something went wrong: " +
e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_M/Client.java
Server 1:
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class Server1Impl
extends UnicastRemoteObject
implements MyServer
{
private String name;
public Server1Impl(String s) throws RemoteException {
name = s;
}
public String sayHello() throws RemoteException {
return "Server1()";
}
public static void main(String args[])
{
// Create and install a security manager
// System.setSecurityManager(new RMISecurityManager());
try {
Server1Impl obj = new Server1Impl("Server1");
Naming.rebind("//yps:2001/Server1", obj);
System.out.println("Server1 bound in registry");
} catch (Exception e) {
System.out.println("Server1Impl err: "
+ e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_M/Server1Impl.java
Server 2:
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class Server2Impl
extends UnicastRemoteObject
implements MyServer
{
private String name;
public Server2Impl(String s) throws RemoteException {
name = s;
}
public String sayHello() throws RemoteException {
return "Server2()";
}
public static void main(String args[])
{
// Create and install a security manager
// System.setSecurityManager(new RMISecurityManager());
try {
Server2Impl obj = new Server2Impl("Server2");
Naming.rebind("//yps:2001/Server2", obj);
System.out.println("Server2Server bound in registry");
} catch (Exception e) {
System.out.println("Server2Impl err: "
+ e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_M/Server2Impl.java
% make rmic Server1Impl rmic Server2Impl javac Client.java rmiregistry 2001 & sleep 1 java Server1Impl & java Server2Impl & sleep 4 Server2Server bound in registry Server1 bound in registry java Client Server1() Server2()
Client:
import java.rmi.*;
import java.math.*;
public class Client {
public static void doIt(String catServer, String mouseServer, int port) {
MyServer aCatServer;
MyServer aMouseServer;
Point aPoint = new Point(4, 2 );
System.out.println("In Client: cat is on: " + catServer );
System.out.println("In Client: mouse is on: " + mouseServer );
System.out.println("In Client: port is: " + port );
try {
aCatServer = (MyServer)Naming.lookup("rmi://" +
catServer + ":" + port + "/CatServer");
aMouseServer = (MyServer)Naming.lookup("rmi://" +
mouseServer + ":" + port + "/MouseServer");
// -------------- Cat --------------------
System.out.println("In Client: aCatServer.movePoint(aPoint): " +
(aPoint = aCatServer.movePoint(aPoint)).toString() );
System.out.println("In Client: aCatServer.movePoint(aPoint): " +
aCatServer.movePoint(aPoint).toString() );
System.out.println("In Client: aCatServer.movePoint(aPoint): " +
aCatServer.movePoint(aPoint).toString() );
// -------------- Mouse --------------------
System.out.println("In Client: aMouseServer.movePoint(aPoint): " +
(aPoint = aMouseServer.movePoint(aPoint)).toString() );
System.out.println("In Client: aMouseServer.movePoint(aPoint): " +
aMouseServer.movePoint(aPoint).toString() );
System.out.println("In Client: aMouseServer.movePoint(aPoint): " +
aMouseServer.movePoint(aPoint).toString() );
} catch (Exception e) {
System.out.println("Something went wrong: " +
e.getMessage());
e.printStackTrace();
}
}
public static void main(String args[] ) {
int port = 1099;
String catServer = "yps";
String mouseServer = "yps";
if ( args.length >= 1 )
catServer = args[0];
if ( args.length >= 2 )
mouseServer = args[1];
if ( args.length == 3 )
try {
port = Integer.parseInt(args[2]);
}
catch ( NumberFormatException e ) {
System.out.println("Hm , port = " +
args[2] + " is not valid.");
System.exit(1);
}
if ( args.length > 3 ) {
System.out.println("Usage: " +
"java Client [CatServer [MouseServer [port]]]");
System.exit(1);
}
doIt(catServer, mouseServer, port);
}
}
Source Code: Src//16_MS/Client.java
Interface:
public interface MyServer extends java.rmi.Remote {
Point movePoint(Point aPoint) throws java.rmi.RemoteException;
int getX() throws java.rmi.RemoteException;
int getY() throws java.rmi.RemoteException;
}
Source Code: Src//16_MS/MyServer.java
Cat Server
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class CatServer extends UnicastRemoteObject implements MyServer
{
final private int DELTA = 10;
private int x;
private int y;
private Point aPoint;
public CatServer() throws RemoteException {
;
}
public Point movePoint(Point aPoint) throws RemoteException {
System.out.println("\tIN CatServer: movePoint(): "
+ aPoint.toString() );
return aPoint.move(DELTA, DELTA);
}
public int getX() throws RemoteException {
System.out.println("\tCIN atServer: getX(): " + x );
return x;
}
public int getY() throws RemoteException {
System.out.println("\tCIN atServer: getY(): " + y );
return x;
}
public static void main(String args[])
{
int port = 1099;
// System.setSecurityManager(new RMISecurityManager());
if ( args.length == 1 )
try {
port = Integer.parseInt(args[0]);
}
catch ( NumberFormatException e ) {
System.out.println("Hm , port = " +
args[0] + " is not valid.");
System.exit(1);
}
try {
CatServer obj = new CatServer();
System.out.println("\tIN CatServer: " +
"rmi://:" + port + "/CatServer");
Naming.rebind("rmi://:" + port + "/CatServer", obj);
System.out.println("\tIN CatServer bound in registry");
} catch (RemoteException e) {
System.out.println("CatServer RemoteException ");
e.printStackTrace();
} catch (Exception e) {
System.out.println("CatServer err: "
+ e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src//16_MS/CatServer.java
Point Class:
/**
* This class implements a point in a two dimensional
* area.
* All methods print the method name, when they are called.
* state information includes:
*
* @version $Id$
*
* RIT's home page: <a href="http://www.cs.rit.edu/~hpb">RIT</a>
*
* Revisions:
* $Log$
*/
import java.io.*;
public class Point implements Serializable {
private int x; // x coordinate of the point
private int y; // y cooridnate of the point
/**
* Constructor.
* initialize x and y values of a point
*
* @param x x coordinate
* @param y y coordinate
*
* @return a Point object
*/
public Point(int _x, int _y){
this.x = _x;
this.y = _y;
}
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}
private void readObject(ObjectInputStream s) throws IOException {
try {
s.defaultReadObject();
}
catch ( ClassNotFoundException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
/**
* initialzes x and y of a point.
*
* @param x int x coordinate
* @param y int y coordinate
*
* @return a Point object
*/
public Point initPoint(int _x, int _y){
this.x = _x;
this.y = _y;
return this;
}
/**
* moves a point
*
* @param _x int delta x value
* @param _y int delta y value
*
* @return a Point object
*/
public Point move(int _x, int _y){
this.x += _x;
this.y += _y;
return this;
}
/**
* Returns the x coordinate of a point
*
* @return x value
*/
public int getX(){
return this.x;
}
/**
* Returns the y coordinate of a point
*
* @return y value
*/
public int getY(){
return this.y;
}
/**
* Returns a String reperesentation of the point
*
* @return String reprasentation of the point
*/
public String toString(){
return "Point at (" + x + "/" + y + ")";
}
}
Source Code: Src/16_MS/Point.java
Makefile:
1 2 3 all: Point.class \ 4 CatServer_Skel.class CatServer_Stub.class \ 5 MouseServer_Skel.class MouseServer_Stub.class \ 6 MyServer.class Client.class 7 8 fireItUp 9 10 11 CatServer_Skel.class CatServer_Stub.class: CatServer.java 12 rmic CatServer 13 MouseServer_Skel.class MouseServer_Stub.class: MouseServer.java 14 rmic MouseServer 15 16 MyServer.class: MyServer.java 17 javac MyServer.java 18 19 Client.class: Client.java 20 javac Client.java 21 22 CatServer.class: CatServer.java 23 javac CatServer.java 24 25 MouseServer.class: MouseServer.java 26 javac MouseServer.java 27 28 Point.class: Point.java 29 javac Point.java 30 31 clean: 32 rm -f *class
Source Code: Src/16_MS/makefile
Result:
IN CatServer: //yps:2001/CatServer
IN MouseServer: /yps:2001/MouseServer
IN CatServer bound in registry
In Client: cat is on: yps
In Client: mouse is on: yps
In Client: port is: 2001
IN MouseServer bound in registry
IN CatServer: movePoint(): Point at (4/2)
In Client: aCatServer.movePoint(aPoint): Point at (14/12)
IN CatServer: movePoint(): Point at (14/12)
In Client: aCatServer.movePoint(aPoint): Point at (24/22)
IN CatServer: movePoint(): Point at (14/12)
In Client: aCatServer.movePoint(aPoint): Point at (24/22)
Start of a fireItUp Script:
1 #!/bin/sh
2
3 KILL_IT="killIt; killIt java"
4 ME="`who am i | sed 's/ .*//'`"
5 HOSTNAME="`hostname`"
6 USEDHOSTS="yps yps yps" # <-- modify here ...
7 WD=`pwd`
8
9
10 remote_cmd() # bg host cmd
11 {
12 echo "$HOSTNAME $ME" > $HOME/.rhosts
13 if [ $1 = "bg" ]
14 then
15 rsh $2 "rm -f $HOME/.rhosts; cd $WD && $3" &
16 else
17 rsh $2 "rm -f $HOME/.rhosts; cd $WD && $3"
18 fi
19 }
20
21 kill_all()
22 {
23 for i in $USEDHOSTS
24 do
25 remote_cmd fg $i "$KILL_IT" 2>&1 > /dev/null
26 done
27 }
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 kill_all
43 sleep 2
44
45 echo 1
46 rmiregistry &
47 echo "Waiting for rmiregistry .... chrr ... "; sleep 1
48 java CatServer &
49
50 echo 2
51 remote_cmd bg yps "rmiregistry &"
52
53 echo 3
54 echo "Waiting for rmiregistry .... chrr ... "; sleep 2
55 remote_cmd bg yps "java MouseServer &"
56
57 echo 4
58 echo "Waiting for the servers .... chrr ... "; sleep 2
59 remote_cmd fg yps "java Client $HOSTNAME stones"
60
61 kill_all
62
63 exit 0
64
Source Code: Src/16_MS/fireItUp
% make
javac Client.java
rmiregistry &
sleep 1
java PiServer &
sleep 4
PiServer: PiServer()
PiServer bound in registry
java Client
3.1415926536
% java Client 100
3.141592653589793238462643383279502884197
16939937510582097494459230781640628620899
86280348253421170680
%
Server Interface:
public interface MyServer extends java.rmi.Remote {
String sayHello() throws java.rmi.RemoteException;
}
Source Code: Src/16_M/MyServer.java
Immutable, arbitrary-precision signed decimal numbers. A BigDecimal consists of an arbitrary precision integer value and a non-negative integer scale, which represents the number of decimal digits to the right of the decimal point. (The number represented by the BigDecimal is intVal/7**scale.) BigDecimals provide operations for basic arithmetic, scale manipulation, comparison, format conversion and hashing. The compute engine, a remote object in the server, takes tasks from clients, runs them, and returns any results. The tasks are run on the machine where the server is running. This sort of distributed application could allow a number of client machines to make use of a particularly powerful machine or one that has specialized hardware.
Client:
import java.rmi.*;
import java.math.*;
public class Client {
public static void doIt(String host, String port, int digits) {
String message = "";
try {
MyServer obj = (MyServer)Naming.lookup("//" +
host + ":" + port + "/PiServer");
System.out.println(obj.computePi(digits));
} catch (Exception e) {
System.out.println("Something went wrong: " +
e.getMessage());
e.printStackTrace();
}
}
public static void main(String args[] ) {
int digits = 10;
String host = "yps";
String port = "";
if ( args.length >= 1 ) {
try {
digits = Integer.parseInt(args[0]);
}
catch ( NumberFormatException e ) {
System.out.println("Hm , digits = " + args[0]);
System.exit(1);
}
}
if ( args.length >= 2 ) {
host = args[1];
}
if ( args.length == 3 ) {
try {
port = args[2];
Integer.parseInt(port);
}
catch ( NumberFormatException e ) {
System.out.println("Port = " + port + " is not valid.");
System.exit(1);
}
}
if ( args.length > 3 ) {
System.out.println("Usage: java Client [digits [host [port]]]");
System.exit(1);
}
doIt(host, port, digits);
}
}
Source Code: Src/16_C/Client.java Interface:
import java.math.*;
public interface MyServer extends java.rmi.Remote {
BigDecimal computePi(int digits)
throws java.rmi.RemoteException;
}
Source Code: Src/16_C/MyServer.java
Server:
import java.rmi.*;
import java.math.*;
import java.rmi.server.UnicastRemoteObject;
public class PiServer
extends UnicastRemoteObject
implements MyServer
{
/** constants used in pi computation */
private static final BigDecimal ZERO =
BigDecimal.valueOf(0);
private static final BigDecimal ONE =
BigDecimal.valueOf(1);
private static final BigDecimal FOUR =
BigDecimal.valueOf(4);
/** rounding mode to use during pi computation */
private static final int roundingMode =
BigDecimal.ROUND_HALF_EVEN;
/** digits of precision after the decimal point */
private int digits;
/**
* Construct a task to calculate pi to the specified
* precision.
*/
public PiServer() throws RemoteException {
System.out.println("\tPiServer: PiServer()");
}
/**
* Compute the value of pi to the specified number of
* digits after the decimal point. The value is
* computed using Machin's formula:
*
* pi/4 = 4*arctan(1/5) - arctan(1/239)
*
* and a power series expansion of arctan(x) to
* sufficient precision.
*/
public BigDecimal computePi(int digits) throws RemoteException {
int scale = digits + 5;
BigDecimal arctan1_5 = arctan(5, scale);
BigDecimal arctan1_239 = arctan(239, scale);
BigDecimal pi = arctan1_5.multiply(FOUR).subtract(
arctan1_239).multiply(FOUR);
return pi.setScale(digits,
BigDecimal.ROUND_HALF_UP);
}
/**
* Compute the value, in radians, of the arctangent of
* the inverse of the supplied integer to the speficied
* number of digits after the decimal point. The value
* is computed using the power series expansion for the
* arc tangent:
*
* arctan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 +
* (x^9)/9 ...
*/
public static BigDecimal arctan(int inverseX,
int scale)
{
BigDecimal result, numer, term;
BigDecimal invX = BigDecimal.valueOf(inverseX);
BigDecimal invX2 =
BigDecimal.valueOf(inverseX * inverseX);
numer = ONE.divide(invX, scale, roundingMode);
result = numer;
int i = 1;
do {
numer =
numer.divide(invX2, scale, roundingMode);
int denom = 2 * i + 1;
term =
numer.divide(BigDecimal.valueOf(denom),
scale, roundingMode);
if ((i % 2) != 0) {
result = result.subtract(term);
} else {
result = result.add(term);
}
i++;
} while (term.compareTo(ZERO) != 0);
return result;
}
public static void main(String args[])
{
// Create and install a security manager
// System.setSecurityManager(new RMISecurityManager());
try {
PiServer obj = new PiServer();
Naming.rebind("//yps:2042/PiServer", obj);
System.out.println("PiServer bound in registry");
} catch (Exception e) {
System.out.println("PiServer err: " + e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_C/PiServer.java
Interface:
import java.util.*;
public interface HashTableInterface extends java.rmi.Remote {
Hashtable playWithAHashTable(String t)
throws java.rmi.RemoteException;
}
Source Code: Src/16_Hash/HashTableInterface.java
Client:
import java.rmi.*;
import java.util.*;
public class HashTableC {
public static void main(String args[] ) {
String plusMovie = "Smoke Signals";
Hashtable aHashTable = new Hashtable();
aHashTable.put("plusplus Movie", "Comedian Harmonists");
System.out.println("Client: aHashTable local = " +
aHashTable.toString());
try {
HashTableInterface obj =
(HashTableInterface)Naming.lookup("//yps/HelloServer");
aHashTable = obj.playWithAHashTable(plusMovie);
} catch (Exception e) {
System.out.println("HelloApplet exception: " +
e.getMessage());
e.printStackTrace();
}
System.out.println("Client: aHashTable remote = " +
aHashTable.toString());
}
}
Source Code: Src/16_Hash/HashTableC.java
Server:
import java.util.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class HashTableServer
extends UnicastRemoteObject
implements HashTableInterface {
private String name;
public HashTableServer(String s) throws RemoteException {
System.out.println(
"\tHashTableServer: HashTableServer(String s)");
name = s;
}
public Hashtable playWithAHashTable(String t)
throws java.rmi.RemoteException {
Hashtable aHashTable = new Hashtable();
aHashTable.put("plusplus Movie", t);
System.out.println("\tserver: aHashTable = " +
aHashTable.toString());
t = "done";
return aHashTable;
}
public static void main(String args[])
{
// System.setSecurityManager(new RMISecurityManager());
try {
HashTableServer obj = new HashTableServer("HelloServer");
Naming.rebind("//yps/HelloServer", obj);
System.out.println("HelloServer bound in registry");
} catch (Exception e) {
System.out.println("HashTableServer err: " + e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_Hash/HashTableServer.java
Result:
% make
rmic HashTableServer
javac HashTableC.java
rmiregistry &
sleep 1
java HashTableServer &
sleep 4
HashTableServer: HashTableServer(String s)
HelloServer bound in registry
java HashTableC
Client: aHashTable = {plusplus Movie=Comidian Harmonists}
server: aHashTable = {plusplus Movie=Smoke Signals}
Client: aHashTable = {plusplus Movie=Smoke Signals}
Client: plusMovie = Smoke Signals
killIt java
kill -9 27386
Killed
killIt
kill -9 27366
kill -9 27374
# make clean
How does a remote method gets executed?
The Interface:
public interface MultiTInterface extends java.rmi.Remote {
String comeBackASAP() throws java.rmi.RemoteException;
String sleepForAwhile() throws java.rmi.RemoteException;
}
Source Code: Src/16_T/MultiTInterface.java
The Client:
import java.rmi.*;
public class MultiTC {
public static void main(String args[] ) {
String message = "";
System.out.println("Going ... ");
try {
MultiTInterface obj =
(MultiTInterface)Naming.lookup("//spiegel:2001/MultiTServer");
if ( args.length == 0 ) {
System.out.println("Call sleepForAwhile ...");
message = obj.sleepForAwhile();
System.out.println(message);
} else {
System.out.println("Call comeBackASAP ...");
message = obj.comeBackASAP();
System.out.println(message);
}
} catch (Exception e) {
System.out.println("Something went wrong: " +
e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_T/MultiTC.java
The Server:
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class MultiTImpl
extends UnicastRemoteObject
implements MultiTInterface
{
private String name;
public MultiTImpl(String s) throws RemoteException {
name = s;
}
public String sleepForAwhile() throws RemoteException {
try {
Thread.sleep(2000);
} catch ( Exception e ) {
e.printStackTrace();
}
return "sleepForAwhile";
}
public String comeBackASAP() throws RemoteException {
return "comeBackASAP";
}
public static void main(String args[])
{
try {
MultiTImpl obj = new MultiTImpl("MultiTServer");
Naming.rebind("//spiegel:2001/MultiTServer", obj);
System.out.println("MultiTServer bound in registry");
} catch (Exception e) {
System.out.println("MultiTImpl err: " + e.getMessage());
e.printStackTrace();
}
}
}
Source Code: Src/16_T/MultiTImpl.java
The makefile:
1 2 3 all: MultiTInterface.class MultiTC.class MultiTImpl.class \ 4 MultiTImpl_Skel.class MultiTImpl_Stub.class 5 rmiregistry 2001 & 6 sleep 1 7 java MultiTImpl & 8 sleep 4 9 java MultiTC 1 & 10 java MultiTC & 11 killIt java 12 killIt 13 14 15 MultiTImpl_Skel.class MultiTImpl_Stub.class: MultiTImpl.java 16 rmic MultiTImpl 17 18 MultiTInterface.class: MultiTInterface.java 19 javac MultiTInterface.java 20 21 MultiTC.class: MultiTC.java 22 javac MultiTC.java 23 24 MultiTImpl.class: MultiTImpl.java 25 javac MultiTImpl.java 26 27 clean: 28 rm -f *class
Source Code: Src/16_T/makefile
RMI allows parameters, return values and exceptions passed in RMI calls to be any object that is serializable. RMI uses the object serialization mechanism to transmit data from one virtual machine to another and also annotates the call stream with the appropriate location information so that the class definition files can be loaded at the receiver.
When parameters and return values for a remote method invocation are unmarshalled to become live objects in the receiving VM, class definitions are required for all of the types of objects in the stream. The unmarshalling process first attempts to resolve classes by name in its local class loading context (the context class loader of the current thread). RMI also provides a facility for dynamically loading the class definitions for the actual types of objects passed as parameters and return values for remote method invocations from network locations specified by the transmitting endpoint. This includes the dynamic downloading of remote stub classes corresponding to particular remote object implementation classes (and used to contain remote references) as well as any other type that is passed by value in RMI calls, such as the subclass of a declared parameter type, that is not already available in the class loading context of the unmarshalling side.
To support dynamic class loading, the RMI runtime uses special subclasses of java/io.ObjectOutputStream and java/io.ObjectInputStream for the marshal streams that it uses for marshalling and unmarshalling RMI parameters and return values.
|
|