Exercises

Included below are short-answer and programming exercises. Answers are provided for those exercises whose exercise number is a hyperlink. Because college faculty use these exercises in their exams, we have provided answers to roughly half of the exercises included here.


21.3 Distinguish between connection-oriented network services and connectionless network services.

21.4 How does a client determine the host name of the client computer?

21.5 Under what circumstances would a SocketException be thrown?

21.6 How can a client get a line of text from a server?

21.7 Describe how a client applet or application can read a file from a server through a URL connection.

21.8 Describe how a client connects to a server.

21.9 Describe how a server sends data to a client.

21.10 Describe how to prepare a server to receive a streams-based connection request from a single client.

21.11 Describe how to prepare a server to receive connection requests from multiple clients where each client that connects should be processed in parallel with all other connected clients.

21.12 How does a server listen for connections at a port?

21.13 What determines how many connect requests from clients can wait in a queue to connect to a server?

21.14 As described in the text, what reasons might cause a server to refuse a connection request from a client?

21.15 Use a socket connection to allow a client to specify a file name and have the server send the contents of the file or indicate that the file does not exist.

21.16 Modify Exercise 21.15 to allow the client to modify the contents of the file and send the file back to the server for storage. The user can edit the file in a JTextArea, then click a save changes button to send the file back to the server.

21.17 Modify program of Fig. 21.1 to allow users to add their own sites to the list and remove sites from the list.

21.18 Multithreaded servers are quite popular today, especially because of the increasing use of multiprocessing servers. Modify the simple server application presented in Section 21.6 to be a multi- threaded server. Then use several client applications and have each of them connect to the server simultaneously.

21.19 In the text we presented a tic-tac-toe program controlled by a multithreaded server. Develop a checkers program modeled after the tic-tac-toe program. The two users should alternate making moves. Your program should mediate the players' moves, determining whose turn it is and allowing only valid moves. The players themselves will determine when the game is over.

21.20 Develop a chess-playing program modeled after the checkers program in the previous exercises.

21.21 Develop a black jack card game program in which the server application deals cards to each of the client applets. The server should deal additional cards (as per the rules of the game) to each player as requested.

21.22 Develop a poker card game in which the server application deals cards to each of the client applets. The server should deal additional cards (as per the rules of the game) to each player as requested.

21.23 (Modifications to the Multithreaded Tic-Tac-Toe Program) The programs of Figs. 21.7 and 21.8 implemented a multithreaded, client/server version of the game Tic-Tac-Toe. Our goal in developing this game was to demonstrate a multithreaded server that could process multiple connections from clients at the same time. The server in the example is really a mediator between the two client applets-it makes sure that each move is valid and that each client moves in the proper order. The server does not determine who won or lost or if there was a draw. Also, there is no capability to allow a new game to be played or to terminate an existing game.

The following is a list of suggested modifications to the multithreaded Tic-Tac-Toe application and applet.

  1. Modify the TicTacToeServer class to test for a win, loss or draw on each move in the game. Send a message to each client applet that indicates the result of the game when the game is over.
  2. Modify the TicTacToeClient class to display a button that when clicked allows the client to play another game. The button should only be enabled when a game completes. Note that both class TicTacToeClient and class TicTacToeServer must be modified to reset the board and all state information. Also, the other TicTacToeClient should be notified that a new game is about to begin so its board and state can be reset.
  3. Modify the TicTacToeClient class to provide a button that allows a client to terminate the program at any time. When the button is clicked, the server and the other client should be notified. The server should then wait for a connection from another client so a new game can begin.
  4. Modify the TicTacToeClient class and the TicTacToeServer class so the winner of a game can choose game piece X or O for the next game. Remember: X always goes first.
  5. If you would like to be ambitious, allow a client to play against the server while the server waits for a connection from another client.

21.24 (3-D Multithreaded Tic-Tac-Toe) Modify the multithreaded, client/server Tic-Tac-Toe program to implement a three-dimensional 4-by-4-by-4 version of the game. Implement the server application to mediate between the two clients. Display the three-dimensional board as four boards containing four rows and four columns each. If you would like to be ambitious, try the following modifications:

  1. Draw the board in a three-dimensional manner.
  2. Allow the server to test for a win, loss or draw. Beware! There are many possible ways to win on a 4-by-4-by-4 board!

21.25 (Networked Morse Code) Modify your solution to Exercise 10.26 to enable two applets to send Morse Code messages to each other through a multithreaded server application. Each applet should allow the user to type normal characters in JTextAreas, translate the characters into Morse Code and send the coded message through the server to the other client. When messages are received, they should be decoded and displayed as normal characters and as Morse Code. The applet should have two JTextAreas: one for displaying the other client's messages and one for typing.


Selected Answers

Included below are answers to approximately half the of the exercises in the Cyber Classroom. We are not able to include answers to every exercise because college faculty use these exercises in their classroom exams.


21.3 Distinguish between connection-oriented network services and connectionless network services.
ANS: Connection-oriented services maintain a connection while data is being transferred. Connectionless services do not maintain a connection. Connection-oriented services are generally slower but more reliable.

21.4 How does a client determine the host name of the client computer?
ANS: InetAddress.getLocalHost().getHostName().

21.5 Under what circumstances would a SocketException be thrown?
ANS: If a DatagramSocket cannot be constructed properly, a SocketException is thrown.

21.6 How can a client get a line of text from a server?
ANS: Through the Socket using a stream object (e.g., such as ObjectInputStream).

21.7 Describe how a client applet or application can read a file from a server through a URL connection.
ANS: A client can read a file through a URL connection by creating a URL object and issuing an openStream method call on the URL object. The openStream call returns an InputStream object that can be used to read bytes from the file. Also, a DataInputStream object can be chained to the InputStream returned from openStream to allow other data types to be read from the file on the server.

21.8 Describe how a client connects to a server.
ANS: A client connects to the server by creating a socket using the Socket class constructor. The name of the server and the port to connect to are passed to the Socket constructor. Information can be exchanged between the client and server using the socket?s InputStream and OutputStream.

21.15

// Exercise 21.15 Solution// Client.javaimport java.awt.*;import java.net.*;import java.io.*;import java.awt.event.*;import javax.swing.*;public class Client extends JFrame          implements ActionListener {   private JTextField fileName;   private JTextArea contents;   private BufferedReader bufferInput;   private BufferedWriter bufferOutput;   private Socket connection;   private JPanel p;   private JLabel label;   public Client()   {      p = new JPanel();      label = new JLabel( "Enter file name to retrieve:" );      p.setLayout( new GridLayout( 1, 2, 0, 0 ) );      p.add( label );      fileName = new JTextField();      p.add( fileName );      fileName.selectAll();      fileName.addActionListener( this );      contents = new JTextArea();      Container c = getContentPane();      c.setLayout( new BorderLayout() );      c.add( p, BorderLayout.NORTH );      c.add( contents, BorderLayout.CENTER );      try {         connection = new Socket( InetAddress.getLocalHost(), 5000 );           bufferInput = new BufferedReader( new InputStreamReader( connection.getInputStream() ) );         bufferOutput = new BufferedWriter( new OutputStreamWriter( connection.getOutputStream() ) );      }      catch( IOException ex ) {         ex.printStackTrace();      }      setSize( 300, 300 );      show();   }   public void actionPerformed( ActionEvent e )   {      try {         String t = e.getActionCommand() + "\n";         bufferOutput.write( t, 0, t.length() );         bufferOutput.flush();         String s = bufferInput.readLine();         contents.setText( s );          if ( s.equals( "The file is:" ) ) {            s = bufferInput.readLine();            while ( s != null ) {               contents.append( s + "\n" );               s = bufferInput.readLine();            }         }         fileName.setEditable( false );         fileName.setBackground( Color.lightGray );         fileName.removeActionListener( this );      }      catch ( EOFException eof ) {      }      catch ( IOException ex ) {         ex.printStackTrace();      }   }   public static void main( String args[] )   {      Client p = new Client();      p.addWindowListener(          new WindowAdapter() {            public void windowClosing( WindowEvent e )            {               System.exit( 0 );            }            }      );   }}                                             // Exercise 21.15 Solution// Server.javaimport java.net.*;import java.io.*;public class Server {   private ServerSocket server;   private Socket connection;   private BufferedReader input;   private BufferedWriter output;   public static void main( String args[] )   {      Server s = new Server();      s.runServer();   }   public Server()   {      try {         server = new ServerSocket( 5000, 10 );              }      catch( IOException e ) {         e.printStackTrace();         System.exit( 0 );      }   }   public void runServer()   {      try {         connection = server.accept();         input = new BufferedReader( new InputStreamReader( connection.getInputStream() ) );         output = new BufferedWriter( new OutputStreamWriter( connection.getOutputStream() ) );         File f = new File( input.readLine() );         if ( f.exists() ) {            BufferedReader fileInput =                 new BufferedReader( new InputStreamReader( new FileInputStream( f ) ) );            String s;            output.write( "The file is:\n", 0, 13 );            output.flush();            while ( ( s = ( fileInput.readLine() ) ) != null ) {               output.write( s + '\n', 0, s.length() + 1 );               output.flush();            }            connection.close();         }         else {            String s2 = f.getName() + " does not exist\n";            output.write( s2, 0, s2.length() );            output.flush();         }      }      catch( IOException e ) {         System.err.println( "IOException has occurred!" );         e.printStackTrace();         System.exit( 0 );      }   }}

21.18

// Exercise 24.18 Solutionimport java.io.*;import java.net.*;import java.awt.*;import java.awt.event.*;import javax.swing.*;public class Client extends JFrame {   private JTextField enter;   private JTextArea display;   ObjectOutputStream output;   ObjectInputStream input;   String message = "";   public Client()   {      super( "Client" );      Container c = getContentPane();      enter = new JTextField();      enter.setEnabled( false );      enter.addActionListener(         new ActionListener() {            public void actionPerformed( ActionEvent e )            {               sendData( e.getActionCommand() );            }         }      );      c.add( enter, BorderLayout.NORTH );      display = new JTextArea();      display.setEnabled( false );      c.add( new JScrollPane( display ),             BorderLayout.CENTER );      setSize( 300, 150 );      show();   }   public void runClient()    {      Socket client;      try {         display.setText( "Attempting connection\n" );         client = new Socket(             InetAddress.getByName( "127.0.0.1" ), 5558 );         display.append( "Connected to: " +            client.getInetAddress().getHostName() );         output = new ObjectOutputStream(                      client.getOutputStream() );         output.flush();         input = new ObjectInputStream(                     client.getInputStream() );         display.append( "\nGot I/O streams\n" );         enter.setEnabled( true );         do {            try {               message = ( String ) input.readObject();               display.append( "\n" + message );               display.setCaretPosition(                  display.getText().length() );            }            catch ( ClassNotFoundException cnfex ) {               display.append(                  "\nUnknown object type received" );            }         } while ( !message.equals( "SERVER>>> TERMINATE" ) );         display.append( "Closing connection.\n" );         output.close();         input.close();         client.close();         display.append( "Connection closed." );      }      catch ( EOFException eof ) {         System.err.println( "Server terminated connection" );      }      catch ( IOException e ) {         e.printStackTrace();      }   }   private void sendData( String s )   {      try {         message = s;         output.writeObject( "CLIENT>>> " + s );         output.flush();         display.append( "\nCLIENT>>>" + s );      }      catch ( IOException cnfex ) {         display.append(            "\nError writing object" );      }   }   public static void main( String args[] )   {      Client app = new Client();      app.addWindowListener(         new WindowAdapter() {            public void windowClosing( WindowEvent e )            {               System.exit( 0 );            }         }      );      app.runClient();   }}// Exercise 24.18 Solution// Serverimport java.io.*;import java.net.*;import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.util.*;public class Server extends JFrame {   private JTextField enter;   private JTextArea display;   private Vector clients;   public Server()   {      super( "Server" );      Container c = getContentPane();      enter = new JTextField();            enter.addActionListener(         new ActionListener() {            public void actionPerformed( ActionEvent ae )            {               Enumeration e = clients.elements();               while ( e.hasMoreElements() )                  ( ( ClientThread ) e.nextElement() ).sendData(                     ae.getActionCommand() );            }         }      );      c.add( enter, BorderLayout.NORTH );      display = new JTextArea();      display.setEnabled( false );      c.add( new JScrollPane( display ),             BorderLayout.CENTER );      setSize( 300, 150 );      show();   }   public void runServer()   {            try {                  ServerSocket server = new ServerSocket( 5558, 100 );         clients = new Vector();         while ( true ) {                        display.append( "Waiting for connection\n" );                       clients.add( new ClientThread( server.accept(),                                           display ) );            ( ( ClientThread ) clients.lastElement() ).start();         }      }      catch ( IOException io ) {         io.printStackTrace();      }   }   public static void main( String args[] )   {      Server app = new Server();      app.addWindowListener(         new WindowAdapter() {            public void windowClosing( WindowEvent e )            {               System.exit( 0 );            }         }      );      app.runServer();   }}class ClientThread extends Thread {   private static int clientNumber;   private Socket con;   private ObjectOutputStream output;   private ObjectInputStream input;   private JTextArea display;   public ClientThread( Socket s, JTextArea display )   {           this.display = display;      clientNumber++;      con = s;      try {         output = new ObjectOutputStream(            con.getOutputStream() );         output.flush();         input = new ObjectInputStream( con.getInputStream() );         sendData( "Connection successful" );         this.display.append( "\nConnection " + clientNumber +            " received from: " +            con.getInetAddress().getHostName() + "\n" );      }      catch ( StreamCorruptedException sce ) {                  sce.printStackTrace();      }      catch ( IOException iex ) {         iex.printStackTrace();      }   }   public static int getClientNumber() { return clientNumber; }   public void sendData( String message )   {      try {         output.writeObject( "SERVER>>> " + message );         output.flush();         display.append( "\nSERVER>>>" + message );      }      catch ( IOException cnfex ) {         display.append( "\nError writing object" );      }          }   public void run()   {      String message = null;      try {         do {            try {               Thread.sleep( 50 );               message = ( String ) input.readObject();               display.append( "\n" + message );               display.setCaretPosition(                  display.getText().length() );            }            catch ( ClassNotFoundException cnfex ) {               display.append(                  "\nUnknown object type received" );            }            catch ( InterruptedException ie ) {               ie.printStackTrace();            }         } while ( !message.equals( "CLIENT>>> TERMINATE" ) );                     display.append( "\nClient terminated connection" );         display = null;         output.close();         input.close();         con.close();      }      catch ( IOException ioex ) {         ioex.printStackTrace();      }   }}/************************************************************************** * (C) Copyright 1999 by Deitel & Associates, Inc. and Prentice Hall.     * * All Rights Reserved.                                                   * *                                                                        * * DISCLAIMER: The authors and publisher of this book have used their     * * best efforts in preparing the book. These efforts include the          * * development, research, and testing of the theories and programs        * * to determine their effectiveness. The authors and publisher make       * * no warranty of any kind, expressed or implied, with regard to these    * * programs or to the documentation contained in these books. The authors * * and publisher shall not be liable in any event for incidental or       * * consequential damages in connection with, or arising out of, the       * * furnishing, performance, or use of these programs.                     * *************************************************************************/