Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Programming Section 10 Lab Exercises September 2003 By James King Contents Contents ......................................................................................................................... 2 Table of Figures ............................................................................................................. 2 Section 10 Advanced network Programming ................................................................ 3 Handling Multiple Clients.......................................................................................... 3 Java Remote Method Invocation (RMI) .................................................................... 4 Setting up, Compiling and Running Java RMI clients. Servers and Registry ........... 7 Stubs....................................................................................................................... 7 Registry .................................................................................................................. 7 server ...................................................................................................................... 7 client ....................................................................................................................... 7 Table of Figures Error! No table of figures entries found. 2 Section 10 Advanced network Programming Do not try this section until you have read and understand Java Serialization, Multiple threads and the networking section. Handling Multiple Clients Both Java accept and receive block (i.e. stop the thread that calls them) until a connection is made or there is data available to read. This means the thread that calls accept or receive cannot do anything else until the wait is over. So if we program the server with a single thread then only one client can connect to the server at a time. Most of the time we want to be able to handle multiple clients and therefore the server must be multi-threaded. There is potentially a similar problem for the client. If the client calls receive because it is expecting a reply from the server it will sleep until the reply arrives. This means that if the client has a GUI there is no thread available to process the user clicking the mouse or typing so the GUI will seem to lock up! Worse than this, if the client does not know when data will come from the server. For instance, if the server is a chat server like IRC, then client requires multiple threads one to wait for data from the server and another to send data to the server. It is difficult in network programming to avoid writing multi-threaded programs. Lets modify our hello world TCP server multi-threaded and leave the client as single threaded for now. We will change the server so that as soon as it accepts a clients’ connection it will create a separate thread to handle that connection and loop around again to accept the next client whilst the separate (slave) thread handles the communication with the new client. ServerSocket sv=new ServerSocket(6666,2); while(true) { Socket s=sv.accept(); Thread sl=new Thread(new slave(s)); sl.start(); } The slave thread needs to communicate with the newly connected client so the socket used to communicate with the client is passed to the slave Thread when it is instantiated. 3 public class slave implements Runnable { Socket sock=null; public slave(Socket s) { sock=s; } public void run() { InputStream i=sock.getInputStream(); DataInputStream oi=new DataInputStream(i); String h=oi.readUTF(); Thread.sleep(3000); System.out.println(h); } } To prove the server can accept multiple clients we can add delays in the client so you can run more than one at the same time. Thread.sleep(1000); Sleep makes the thread sleep for 1000 mill-seconds or 1 second. You of course can use a larger number! However, sleep can be interrupted if it is it will cause an Exception therefore you will need a try catch around it! Java Remote Method Invocation (RMI) Up to now, you have called many methods inside you own program such as Monster m=new Monster(); m.take_damage(25); But the only way to communicate with another program (possibly running on anther machine) is to use TCP or UDP network programming. This is not very natural. Why can’t you just call a method in an instance of a class running on another machine or inside a different program and expect Java to figure out how to do it. Java RMI allows you to do just that! With only a little additional code and effort you can call methods in other Java programs running on other machines just as if the method was inside one of you classes inside you program. This is a nice feature of Java. 4 You need to tell Java which methods can be called from the outside world. (For security reasons you might not allow every method in every class to be called from anywhere on the Internet!!!!!!). To do this you create an interface listing each method that you want to be called remotely. import java.rmi.*; public interface remoteserver extends Remote { public void helloworld() throws java.rmi.RemoteException; } All of the Java rmi code is in a package called rmi so you need to import it. The interface must extend Remote and each exported method must be declared as possibly throwing java.rmi.RemoteException. Naturally the interface contains no code so you must write a class that implements this interface and provides code for each method header in the interface. Sounds too simple? Well yes, there are a few more details you need to know to get you remote class available to the rest of the world. Firstly you need to specify the communication system between the callers and you remote object. This is usually java.rmi.server.UnicastRemoteObject UnicastRemoteObject is a Java class in the rmi package and your remotely callable class must extend it as well as implementing the Remote interface. You also need to register you class with the Java remote object invocation registry. This registry stores a list of all the remotely accessible objects and methods and acts as a central directory. You do this by creating an instance of you remotely assessable class and passing it as a parameter to a static method (rebind) in a static class (Naming). You also need to specify which machine the class is running on. The format for this is rather like a URL for a web page. First is the protocol in this case rmi next is the location of the remote class in this case localhost (this machine) and finally is the name of the class in this case server. server s=new server(); Naming.rebind("rmi://localhost/server",s); 5 Bellow is the entire code for the server. import java.rmi.*; import java.rmi.server.*; public class server extends java.rmi.server.UnicastRemoteObject implements remoteserver { public void helloworld() throws java.rmi.RemoteException { System.out.println("hello world"); } public static void main(String args[]) { server s=new server(); Naming.rebind("rmi://localhost/server",s); } } For the client to call a method in the server the client must use the registry to find the server. Calling the lookup method in the Naming class does this. The lookup method needs to know the name of the class to find so you pass the same URL like string as the remote class was registered with Naming.lookup("rmi://localhost/server"); The entire client code is import java.rmi.*; public class client { public static void main(String args[]) { remoteserver s=(remoteserver) Naming.lookup("rmi://localhost/server"); s.helloworld(); } } Naming.lookup returns a stub that can be used to communicate with the remote server. This stub must be typecast into the name of the interface the remote server implements. In this case remoteserver. You can then use the stub to call the remote method helloworld! 6 Setting up, Compiling and Running Java RMI clients. Servers and Registry BlueJ does not fully support Java RMI yet so there are some things you need to do using MS-DOS and the SUN Java Software Development kit (JDK). Stubs The stubs and skeleton are not generated by BlueJ and require a compiler called rmic this is part of the SUN J2sdk you installed along with BlueJ. Load up and command prompt or Msdos window. type in dir, if you are not in the directory that contains your RMI code cd (change directory) to it. Run the rmic compiler on the server by typing in c:\j2sdk1.4.2_01\bin\rmic server (You may need to replace c:\j2sdk1.4.2_01 with the location and version of the Java you have installed.) This should compile the server class and generate the stub and skeleton Registry Before running the server you need to run the registry so using the same MS-DOS window type in c:\j2sdk1.4.2_01\bin\rmiregistry (Again you may need to replace c:\j2sdk1.4.2_01 with the location and version of the Java you have installed. Leave the registry running the entire time you experiment with rmi) Note the registry should be run in the same directory as the RMI class files you have just created. server Run the server from BlueJ as normal and if it crashes with in Exception during the binding then either you have not run the registry or the registry was run in a different directory from the one the server class file is in. client Run the client last in another copy of BlueJ. If the client generates an Exception during the lookup you probably have not run the registry and registered the server. Once the client has run the server should say “hello world”. 7