28.10. Chapter Summary

 
[Page 816 ( continued )]

25.2. Client/Server Computing

Networking is tightly integrated in Java. Socket-based communication is provided that enables programs to communicate through designated sockets. Sockets are the endpoints of logical connections between two hosts and can be used to send and receive data. Java treats socket communications much as it treats I/O operations; thus programs can read from or write to sockets as easily as they can read from or write to files.

Network programming usually involves a server and one or more clients . The client sends requests to the server, and the server responds to the requests . The client begins by attempting to establish a connection to the server. The server can accept or deny the connection. Once a connection is established, the client and the server communicate through sockets.

The server must be running when a client starts. The server waits for a connection request from a client. The statements needed to create a server and a client are shown in Figure 25.1.

Figure 25.1. The server creates a server socket and, once a connection to a client is established, connects to the client with a client socket.
(This item is displayed on page 817 in the print version)


25.2.1. Server Sockets

To establish a server, you need to create a server socket and attach it to a port, which is where the server listens for connections. The port identifies the TCP service on the socket. Port numbers range from 0 to 65536, but port numbers 0 to 1024 are reserved for privileged services. For instance, the email server runs on port 25, and the Web server usually runs on port 80.


[Page 817]

You can choose any port number that is not currently used by any other process. The following statement creates a server socket serverSocket :

 ServerSocket serverSocket =   new   ServerSocket(port); 

Note

Attempting to create a server socket on a port already in use would cause the java.net.BindException .


25.2.2. Client Sockets

After a server socket is created, the server can use the following statement to listen for connections:

 Socket socket = serverSocket.accept(); 

This statement waits until a client connects to the server socket. The client issues the following statement to request a connection to a server:

 Socket socket =   new   Socket(  serverName, port  ); 

This statement opens a socket so that the client program can communicate with the server. serverName is the server's Internet host name or IP address. The following statement creates a socket at port 8000 on the client machine to connect to the host 130.254.204.36 :

 Socket socket =   new   Socket(   "130.254.204.36"   ,   8000   ) 

Alternatively, you can use the domain name to create a socket, as follows :

 Socket socket =   new   Socket(   "drake.armstrong.edu"   ,   8000   ); 

When you create a socket with a host name, the JVM asks the DNS to translate the host name into the IP address.

Note

A program can use the host name localhost or the IP address 127.0.0.1 to refer to the machine on which a client is running.


Note

The Socket constructor throws a java.net.UnknownHostException if the host cannot be found.



[Page 818]

25.2.3. Data Transmission through Sockets

After the server accepts the connection, communication between server and client is conducted the same as for I/O streams. The statements needed to create the streams and to exchange data between them are shown in Figure 25.2.

Figure 25.2. The server and client exchange data through I/O streams on top of the socket.

To get an input stream and an output stream, use the getInputStream() and getOutputStream() methods on a socket object. For example, the following statements create an InputStream stream called input and an OutputStream stream called output from a socket:

 InputStream input = socket.getInputStream(); OutputStream output = socket.getOutputStream(); 

The InputStream and OutputStream streams are used to read or write bytes. You can use DataInputStream , DataOutputStream , BufferedReader , and PrintWriter to wrap on the InputStream and OutputStream to read or write data, such as int , double , or String . The following statements, for instance, create a DataInputStream stream, input , and a DataOutput stream, output , to read and write primitive data values:

 DataInputStream input =   new   DataInputStream (socket.getInputStream()); DataOutputStream output =   new   DataOutputStream (socket.getOutputStream()); 

The server can use input.readDouble() to receive a double value from the client, and output.writeDouble(d) to send double value d to the client.

Tip

Recall that binary I/O is more efficient than text I/O because text I/O requires encoding and decoding. Therefore it is better to use binary I/O for transmitting data between a server and a client to improve performance.


25.2.4. A Client/Server Example

This example presents a client program and a server program. The client sends data to a server. The server receives the data, uses it to produce a result, and then sends the result back to the client. The client displays the result on the console. In this example, the data sent from the client comprises the radius of a circle, and the result produced by the server is the area of the circle (see Figure 25.3).


[Page 819]
Figure 25.3. The client sends the radius to the server; the server computes the area and sends it to the client.


The client sends the radius through a DataOutputStream on the output stream socket, and the server receives the radius through the DataInputStream on the input stream socket, as shown in Figure 25.4(a). The server computes the area and sends it to the client through a DataOutputStream on the output stream socket, and the client receives the area through a DataInputStream on the input stream socket, as shown in Figure 25.4(b). The server and client programs are given in Listings 25.1 and 25.2. Figure 25.5 contains a sample run of the server and the client.

Figure 25.4. (a) The client sends the radius to the server. (b) The server sends the area to the client.

Figure 25.5. The client sends the radius to the server. The server receives it, computes the area, and sends the area to the client.

Listing 25.1. Server.java
(This item is displayed on pages 819 - 820 in the print version)
 1   import   java.io.*; 2   import   java.net.*; 3   import   java.util.*; 4   import   java.awt.*; 5   import   javax.swing.*; 6 

[Page 820]
 7   public class   Server   extends   JFrame { 8  // Text area for displaying contents  9   private   JTextArea jta =   new   JTextArea(); 10 11   public static void   main(String[] args) { 12   new   Server(); 13 } 14 15   public   Server() { 16  // Place text area on the frame  17 setLayout(   new   BorderLayout()); 18 add(   new   JScrollPane(jta), BorderLayout.CENTER); 19 20 setTitle(   "Server"   ); 21 setSize(   500   ,   300   ); 22 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 23 setVisible(   true   );  // It is necessary to show the frame here!  24 25   try   { 26  // Create a server socket  27  ServerSocket serverSocket =   new   ServerSocket(   8000   );  28 jta.append(   "Server started at "   +   new   Date() +   '\n'   ); 29 30  // Listen for a connection request  31  Socket socket = serverSocket.accept();  32 33  // Create data input and output streams  34  DataInputStream inputFromClient =   new   DataInputStream(  35  socket.getInputStream());  36  DataOutputStream outputToClient =   new   DataOutputStream(  37  socket.getOutputStream());  38 39   while   (   true   ) { 40  // Receive radius from the client  41    double   radius = inputFromClient.readDouble();  42 43  // Compute area  44   double   area = radius * radius * Math.PI; 45 46  // Send area back to the client  47  outputToClient.writeDouble(area);  48 49 jta.append(   "Radius received from client: "   + radius +   '\n'   ); 50 jta.append(   "Area found: "   + area +   '\n'   ); 51 } 52 } 53   catch   (IOException ex) { 54 System.err.println(ex); 55 } 56 } 57 } 

Listing 25.2. Client.java
(This item is displayed on pages 820 - 822 in the print version)
 1   import   java.io.*; 2   import   java.net.*; 3   import   java.awt.*; 4   import   java.awt.event.*; 5   import   javax.swing.*; 6 

[Page 821]
 7   public class   Client   extends   JFrame { 8  // Text field for receiving radius  9   private   JTextField jtf =   new   JTextField(); 10 11  // Text area to display contents  12   private   JTextArea jta =   new   JTextArea(); 13 14  // IO streams  15   private   DataOutputStream toServer; 16   private   DataInputStream fromServer; 17 18   public static void   main(String[] args) { 19   new   Client(); 20 } 21 22   public   Client() { 23  // Panel p to hold the label and text field  24 JPanel p =   new   JPanel(); 25 p.setLayout(   new   BorderLayout()); 26 p.add(   new   JLabel(   "Enter radius"   ), BorderLayout.WEST); 27 p.add(jtf, BorderLayout.CENTER); 28 jtf.setHorizontalAlignment(JTextField.RIGHT); 29 30 setLayout(   new   BorderLayout()); 31 add(p, BorderLayout.NORTH); 32 add(   new   JScrollPane(jta), BorderLayout.CENTER); 33 34 jtf.addActionListener(   new   ButtonListener());  // Register listener  35 36 setTitle(   "Client"   ); 37 setSize(   500   ,   300   ); 38 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 39 setVisible(   true   );  // It is necessary to show the frame here!  40 41   try   { 42  // Create a socket to connect to the server  43  Socket socket =   new   Socket(   "localhost"   ,   8000   );  44  // Socket socket = new Socket("130.254.204.36", 8000);  45  // Socket socket = new Socket("drake.Armstrong.edu", 8000);  46 47  // Create an input stream to receive data from the server  48  fromServer =   new   DataInputStream(  49  socket.getInputStream());  50 51  // Create an output stream to send data to the server  52  toServer =  53    new   DataOutputStream(socket.getOutputStream());  54 } 55   catch   (IOException ex) { 56 jta.append(ex.toString() +   '\n'   ); 57 } 58 } 59 60   private class   ButtonListener   implements   ActionListener { 61   public void   actionPerformed(ActionEvent e) { 62   try   { 63  // Get the radius from the text field  64   double   radius = Double.parseDouble(jtf.getText().trim()); 65 66  // Send the radius to the server  

[Page 822]
 67  toServer.writeDouble(radius);  68  toServer.flush();  69 70  // Get area from the server  71   double   area =  fromServer.readDouble()  ; 72 73  // Display to the text area  74 jta.append(   "Radius is "   + radius +   "\n"   ); 75 jta.append(   "Area received from the server is "   76 + area +   '\n'   ); 77 } 78   catch   (IOException ex) { 79 System.err.println(ex); 80 } 81 } 82 } 83 } 

You start the server program first, then start the client program. In the client program, enter a radius in the text field and press Enter to send the radius to the server. The server computes the area and sends it back to the client. This process is repeated until one of the two programs terminates.

The networking classes are in the package java.net . This should be imported when writing Java network programs.

The Server class creates a ServerSocket serverSocket and attaches it to port 8000, using this statement (line 27 in Server.java):

 ServerSocket serverSocket =   new   ServerSocket(   8000   ); 

The server then starts to listen for connection requests, using the following statement (line 31 in Server.java):

 Socket socket = serverSocket.accept(); 

The server waits until a client requests a connection. After it is connected, the server reads the radius from the client through an input stream, computes the area, and sends the result to the client through an output stream.

The Client class uses the following statement to create a socket that will request a connection to the server on the same machine (localhost) at port 8000 (line 43 in Client.java):

 Socket socket =   new   Socket(   "localhost"   ,   8000   ); 

If you run the server and the client on different machines, replace localhost with the server machine's host name or IP address. In this example, the server and the client are running on the same machine.

If the server is not running, the client program terminates with a java.net.ConnectException . After it is connected, the client gets input and output streams ”wrapped by data input and output streams ”in order to receive and send data to the server.

If you receive a java.net.BindException when you start the server, the server port is currently in use. You need to terminate the process that is using the server port and then restart the server.

What happens if the setVisible(true) statement in line 23 in Server.java is moved after the try-catch block in line 56 in Server.java? The frame would not be displayed, because the while loop in the try-catch block will not finish until the program terminates.

 


Introduction to Java Programming-Comprehensive Version
Introduction to Java Programming-Comprehensive Version (6th Edition)
ISBN: B000ONFLUM
EAN: N/A
Year: 2004
Pages: 503

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net