The URL class works well if you need a high-level class for accessing data from the Internet. However, you may want to write Java applications that require lower-level network communication, such as client/server applications. For example, you may have to deal with additional security software before accessing a server, or you may need to access a legacy application that requires a more complicated communication protocol.
In typical client/server applications, a communication link exists between the client software and the server software through a mechanism called sockets. Client-based software uses the Java class Socket, and server-based software uses the Java class ServerSocket, both of which are in the java.net package.
To implement this type of communication, you simply need to create an instance of either the Socket or ServerSocket class and then use the stream methods introduced earlier to perform the communication. Many types of constructors are available for the Socket and ServerSocket classes, but the two that follow are the most frequently used.
Socket(String, Int). String is the host name and Int is the port on this host to which to connect.
ServerSocket(Int). Int is the port number used for communication.
The next example contains two Java classes, Jsap1006 and Jsap1005; Jsap1006 is the client code, and Jsap1005 is the server code. I have programmed this example in the Windows 98 environment and have executed each class in a separate MS-DOS window. If you type in a string on the client window, the client Java program sends the string to the server class, which reverses the characters and then sends the string back to the client class for display. If you type ServerOff on the client side, the server application shuts down. If you type bye in the client application, the client application terminates. As you can see in this example, with the exception of the Socket and ServerSocket classes, all reading and writing is done with streams in a fashion that is very similar to reading or writing to a file or URL.
Listed below is the client side of the client/server example. We try to establish communications with the server, get the user string, and finally make the call to the server application.
import java.io.*; import java.net.*; public class Jsap1006 { public static void main (String[] args) { // Try to establish a connection to the host Socket mySocket = null; byte userInput[] = new byte[256]; PrintWriter os = null; BufferedReader is = null; Character inChar = null; try { mySocket = new Socket("localhost",9876); os = new PrintWriter(mySocket.getOutputStream()); is = new BufferedReader( new InputStreamReader(mySocket.getInputStream())); } catch (UnknownHostException e) { System.out.println(e.getMessage()); return; } catch (IOException e) { System.out.println(e.getMessage()); return; } // Get input from the user and send it to the host try { StringBuffer buf = new StringBuffer(50); int c; String fromServer; while(true) { while((c = System.in.read()) != ‘\n') { if (inChar.isLetterOrDigit((char)c) || c == ‘ ‘) buf.append((char)c); } if (buf.toString().equals("bye")) break; os.println(buf.toString()); os.flush(); buf.setLength(0); fromServer = is.readLine(); System.out.println("Server:" + fromServer); } os.close(); is.close(); mySocket.close(); } catch(UnknownHostException e) { System.out.println(e.getMessage()); } catch(IOException e) { System.out.println(e.getMessage()); } } }
Listed below is the server side of this example. This code locks a port number for communications, waits for a message through this port, reverses the letters, and finally sends the message back.
import java.net.*; import java.io.*; public class Jsap1005 { public static void main (String[] args) { // Attempt to lock onto a port number ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(9876); // Write the host name and port number System.out.println("Host:" + serverSocket.getInetAddress().getHostName()); System.out.println("Port:" + serverSocket.getLocalPort()); } catch (IOException e) { System.out.println(e.getMessage()); return; } // Wait for client message try { Socket clientSocket = null; clientSocket = serverSocket.accept(); BufferedReader is = new BufferedReader( new InputStreamReader( clientSocket.getInputStream())); PrintWriter os = new PrintWriter( new BufferedOutputStream( clientSocket.getOutputStream(), 1024),false); String inputLine; while((inputLine = is.readLine()) != null) { System.out.println("Received:" + inputLine); StringBuffer myBuffer = new StringBuffer(inputLine); os.println(myBuffer.reverse().toString()); os.flush(); if (inputLine.equals("ServerOff")) break; } os.close(); is.close(); clientSocket.close(); serverSocket.close(); } catch (IOException e) { System.out.println(e.getMessage()); return; } } }
Figures 10.2 and 10.3 show how these two programs interact with each other.
Figure 10.2: Client side of sockets example
Figure 10.3: Server side of sockets example
Team-Fly |