package examples.example2_one_client_OO; import java.io.BufferedReader; import java.io.Closeable; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import javax.swing.JOptionPane; /** *
 * NetworkingExamples project: examples.example2_one_client_OO.
 * 
 * A simple example of networking (Sockets) in which:
 *   -- A single Server and Client exchange information, one after the other.
 *   
 * This is the Server code.
 * 
 * This is the same example as {@link examples.example1_one_client}
 * except structured in a more OO way.  In particular, this structure has 3 classes:
 *   -- Main: for starting the program.
 *   -- Server: for initiating and running the Server.
 *   -- Client: for initiating and running the Client.
 * 
 * See {@link examples.example1_one_client#MainForServer} for:
 *   -- Exactly what information the Server and Client exchange in this demo.
 *   -- The 7 Key Statements that are all-you-need-to-know to do networking in Java.
 * 
 * See {@link examples.example3_one_client_OO_library} for this same example
 * but using the simple networking library in package {@link simpleNetworking}.
 * 
* * @author David Mutchler, based on the Java Tutorials on networking. May, 2009. */ public class Server implements Runnable { private Socket socketToCommunicateWithClient; private BufferedReader in; private PrintWriter out; /** *
	 * Constructs readers and writers for talking to the Client, as follows:
	 * 
	 * 1. Constructs a ServerSocket.
	 * 
	 * 2. Use the ServerSocket to accept a connection from a Client
	 *    (blocks -- i.e. waits -- until a Client offers to connect)
	 *    (a better program would establish a timeout for connecting).
	 *    
	 * 3. In accepting a connection to the Client, it gets a Socket.
	 *    Use that Socket to:
	 *    a. Get an InputStream.  Then decorate the InputStream
	 *       into a BufferedReader (for more efficient communication).
	 *    b. Get an OutputStream.  Then decorate the OutputStream
	 *       into a PrintWriter (for convenient ways to write messages).
	 *       
	 * Finally, this constructor:
	 * 4. Starts a Thread in which the Server repeatedly communicates with the
	 *    Client (so that you can see a simple example of network communication).
	 * 
* * @param port Port to use for the ServerSocket * that accepts a connection to the Client. * @throws Throwable if any Exception or Error occurs. */ public Server(int port) throws Throwable { try { //------------------------------------------------------------------------------------- // KEY #1: Construct a ServerSocket that accepts connections from Clients. ServerSocket serverSocket = new ServerSocket(port); //------------------------------------------------------------------------------------- JOptionPane.showMessageDialog(null, "The Server has started and will wait for a connection.\n\n" + "Start the Client AFTER pressing OK in this dialog.\n\n"); //------------------------------------------------------------------------------------- // KEY #2: Block (wait) until a Client connects; // get a Socket for communicating with that Client. this.socketToCommunicateWithClient = serverSocket.accept(); //------------------------------------------------------------------------------------- // Done with the ServerSocket, since we wanted to accept only a single Client in this example. serverSocket.close(); //------------------------------------------------------------------------------------- // KEY #3: From the Socket, construct a BufferedReader for reading from the Client. this.in = new BufferedReader(new InputStreamReader( this.socketToCommunicateWithClient.getInputStream())); //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- // KEY #4: From the Socket, construct a PrintWriter for writing to the Client. this.out = new PrintWriter( this.socketToCommunicateWithClient.getOutputStream(), true); //------------------------------------------------------------------------------------- new Thread(this).start(); } catch (Throwable exception) { this.close(); throw exception; } } /** *
	 * A simple example of communication between this Server and the Client.
	 * 
	 * It behaves as follows:
	 * 
	 * Repeatedly, until the Client sends STOP or the user says to stop:
	 *   -- Get a number from the Client.
	 *   -- Display the number from the Client, and get a number from the user.
	 *   -- Add these numbers and send the total to the Client.
	 *   
	 * The Client can send whatever number it wishes at each iteration;
	 * in fact, the particular Client in this program takes the number
	 * that the Server sends it, chooses a random number between 0 and 10,
	 * and sends the sum back to this Server.
	 * 
	 * If the user says to stop, the Server sends a STOP message to the Client
	 * so that the Client will stop too.
	 * 
*/ @Override public void run() { try { //------------------------------------------------------------------------------------- // Now start communicating with the Client. //------------------------------------------------------------------------------------- String dataFromClient, dataFromUser; int numberFromUser; JOptionPane.showMessageDialog(null, "This Server is running on " + InetAddress.getLocalHost().getCanonicalHostName() + "\n" + "which is IP address " + InetAddress.getLocalHost().getHostAddress() + "\n\n"); while (true) { //----------------------------------------------------------------------------- // KEY #5: Read from the Client. dataFromClient = this.in.readLine(); //----------------------------------------------------------------------------- if (dataFromClient.equals("STOP")) { // Client says to stop. JOptionPane.showMessageDialog(null, "Server ended because the Client asked it to do so.\n\n"); break; } dataFromUser = JOptionPane.showInputDialog( "The number from the Client is " + dataFromClient + ".\n\n" + "What do you want to add to it?\n\n" + "(Or press Cancel to quit this program.)\n\n"); if (dataFromUser == null) { // User selected Cancel in input dialog. JOptionPane.showMessageDialog(null, "Server ended because the user asked it to do so.\n\n" + "Tell the Client to stop too.\n\n"); this.out.println("STOP"); // Tell the Client to stop break; // and stop this Server. } try { numberFromUser = Integer.parseInt(dataFromUser); } catch (NumberFormatException exception) { JOptionPane.showMessageDialog(null, "You entered " + dataFromUser + "\n" + "which is not a number! I will use 0 instead.\n\n"); numberFromUser = 0; } //----------------------------------------------------------------------------- // KEY #6: Write to the Client. this.out.println(Integer.parseInt(dataFromClient) + numberFromUser); //----------------------------------------------------------------------------- } } catch (IOException exception) { System.out.println(exception); JOptionPane.showMessageDialog(null, "Server ended, probably because the user closed the Client.\n\n"); } catch (Throwable exception) { System.out.println(exception); JOptionPane.showMessageDialog(null, "Server ended abnormally.\n\n"); JOptionPane.showMessageDialog(null, exception.getStackTrace()); } this.close(); } /** * Closes all resources that this Server uses: writer, reader, socket. */ void close() { Closeable[] resourcesToClose = {this.out, this.in}; JOptionPane.showMessageDialog(null, "Closing the Server's resources."); for (Closeable resource : resourcesToClose) { try { resource.close(); } catch (Exception exception) { // Ignore; we made our best effort at closing the resource. } } try { this.socketToCommunicateWithClient.close(); } catch (Exception exception) { // Ignore; we made our best effort at closing the resource. } } }