Networking
Two of the main ways of programming networking applications in Java is through sockets and Remote Method Invocation (RMI):
Sockets
Java supports connection to other hosts through the use of sockets. You can use the Socket
class (in package java.net
) to connect to a remote host by specifying an IP address and port number:
Socket socket = new Socket("catalog.example.com", 4321);
You can then obtain an InputStream
and OutputStream
object from the socket to allow you to read and write (subject to any permissions) to the host:
InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream();
In the above case you are the client and the host you are connecting to is the server. If you want to create a server application, you can use the ServerSocket
class:
ServerSocket serverSocket = new ServerSocket(80); // port 80 = http
You then need to wait for clients to connect to your server through the accept()
method, which returns a Socket
object:
Socket clientSocket = serverSocket.accept();
A typical way of coding server programs is to listen for client connections (via accept()
) inside a while loop which continues until the server application is stopped. Each time a client connects, a new Thread
would be created for that client so that multiple clients can connect simultaneously.
Remote Method Invocation (RMI)
Remote Method Invocation provides a means for you to create both a Java server and a Java client program that can communicate with each other without the need to create sockets. Your client object can invoke the methods of the server object just as if they were on the same physical machine, where the RMI mechanism takes care of the network connections for you.
On the server side, you need to define an interface that contains the methods which should be able to be invoked by a remote client. The interface must extend the Remote
interface (in the java.rmi
package), and because network connections are involved which could fail, your method must specify that they throw RemoteException
. Here is a simple interface to convert a String
to uppercase[1]:
package somepackage; import java.rmi.*; public interface WordUtilities extends Remote { public void makeUpperCase(String s) throws RemoteException; }
Also on the server, you need to create a class which implements your interface and extends UnicastRemoteObject
:
package somepackage; import java.rmi.*; public class WordUtilitiesImpl extends UnicastRemoteObject implements WordUtilities { public void makeUpperCase(String s) throws RemoteException { return s.toUpperCase(); } }
Your server program needs to start the RMI registry, an instance of the WordUtilites
object, and bind it to the registry:
try { LocateRegistry.createRegistry(1099); // 1099 is default RMI port WordUtilities wu = new WordUtilitiesImpl(); Naming.rebind("rmi://example.com/wordutilapp", wu); System.out.println("Server has started"); } catch (Exception ex) { ex.printStackTrace(); }
At the client end your application needs to connect to the server host before it can invoke the methods remotely:
try { WordUtilities wu = (WordUtilities) Naming.lookup("rmi://example.com/wordutilapp"); String sUpper = wu.makeUpperCase("make this upper-case"); System.out.println(sUpper); } catch (Exception ex) { ex.printStackTrace(); }
Important:
In a real RMI application you need to protect against untrusted communication, and you would therefore need to set a SecurityManager object at both the server and the client end. This involves defining the files and addresses that are allowed to be accessed and is beyond the scope of this course.
Comments