package examples.example1_one_client; import java.io.BufferedReader; import java.io.Closeable; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.BindException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import javax.swing.JOptionPane; /** *
 * NetworkingExamples project: examples.example1_one_client.
 * 
 * A simple example of networking (Sockets) in which:
 *   -- A single Server and Client exchange information, one after the other.
 * 
 * This is the Server's code.
 *  
 * Brevity is king in this example, so it has few comments / instructions after this
 * and is NOT organized in a OO way that permits easy reuse of code.
 * 
 * See the other examples for an OO approach:
 *   -- {@link examples.example2_one_client_OO} does this same example in a more OO way
 *   -- {@link examples.example3_one_client_OO_library} does this same example
 *           using the simple networking library in package {@link simpleNetworking}
 *   -- {@link examples.example4_two_clients_OO_library} also uses the OO networking library {@link simpleNetworking}
 *   -- {@link examples.example5_chat_OO_library} also uses the OO networking library {@link simpleNetworking}
 *  
 * Run this example by:
 *  
 *  1. On one computer, run MainForServer.
 *  
 *     It starts up, nothing else happens.
 *     
 *  2. On another computer (or the same computer, your choice), run MainForClient.
 *  
 *     It asks in the console window/tab for the hostname of the Server.
 *     Enter the name of the computer running MainForServer.
 *     You can enter    localhost    if you are using a single computer for both processes.
 *
 * You should see (in successive dialog boxes):
 *   -- Server got 42 from the Client and will add 1 to it and thus send 43 to the Client
 *   -- Client got 43 from the Server and will add 10 to it and thus send 53 to the Server
 *   -- Server got 53 from the Client and will add 1 to it and thus send 54 to the Client
 *   -- Client got 54 from the Server and will add 10 to it and thus send 64 to the Server
 * etc
 *  
 * Stop the programs by using the dialog boxes (which ask if you want to continue).
 * Stopping the programs in other ways may prevent them from releasing their resources
 * (and especially the PORT being used).  Also, if the Client stops (for whatever reason)
 * without having connected to the Server, the Server is probably still running (without you
 * noticing it).  In this situation, simply run the Client WITHOUT first starting the Server
 * to clear out the lock / running Server.
 * 
 * Before running this program, you may need to tell your Firewall not to
 * block the port that this program uses (4444, chosen arbitrarily).
 * In Windows, do so by:
 *     Control Panel ~ Windows Firewall ~ Exceptions tab ~ Add Port
 * and enter the port number (4444) with any name you like.
 * 
 * Here is what the Server and Client are doing (to illustrate server/client communication):
 *   -- The Server starts with the number 42 and repeatedly:
 *     -- Adds 1 to its current number.
 *     -- Sends that number to the Client.
 *     -- Gets back a number from the Client
 *        and makes that number the Server's current number.
 *      
 *   -- The Client repeatedly:
 *     -- Gets a number from the Server.
 *     -- Adds 10 to that number.
 *     -- Sends that number back to the Server after pausing a few seconds.
 * 
 * The Server's user can ask it to stop and the Client's user can ask it to stop.
 * In either case, the Server/Client sends a STOP message to the Client/Server to ask it to stop too.
 * 
 * Note that most of the code is for handling errors.  There are only 7 Key Statements
 * (see details in the code) that are all-you-need-to-know to do networking in Java:
 * 
 *   -- Key #1:  Server constructs a ServerSocket.
 *   
 *   -- Key #2:  Server uses its ServerSocket to accept a connection to a Client.
 *               Note that accept blocks (waits) until a Client asks for a Connection.
 *               See Key #7 for how the Client does so.
 *               
 *   -- Key #3:  Constructs a BufferedReader that the Server can use to read
 *               from the Client.  The BufferedReader is constructed from the
 *               Socket that the Server got from Key #2 statement.
 *               
 *   -- Key #4:  Constructs a PrintWriter that the Server can use to write
 *               to the Client.  The PrintWriter is constructed from the
 *               Socket that the Server got from Key #2 statement.
 *               
 *   -- Key #5:  Server reads from the Client by using its BufferedReader.
 *   
 *   -- Key #6:  Server writes to the Client by using its PrintWriter.
 *   
 * For the last Key statement, turn to the Client:
 * 
 *   -- Key #7:  Client constructs a Socket for communicating with the Server.
 *   
 * The Client runs its Key #7 statement while the Server is waiting for
 * its Key #2 statement to complete; the Client's Key #7 statement causes
 * the Server's Key #2 statement to complete.
 * 
 * The Client continues from its Key #7 Statement to do as the Server did:
 *   -- Construct a BufferedReader and PrintReader (as per Key #3 and Key #4).
 *   -- Use the BufferedReader and PrintReader to read from and write to the Server
 *      (as per Key #5 and Key #6).
 * 
 * Reading blocks (waits) for input to arrive; however, there are methods
 * available to see if any input has arrived yet.
 * 
* * @author David Mutchler, based on the Java Tutorials on networking. May, 2009. */ public class MainForServer { /** * Port: Both Server and Client must use the same one, and it must be open. */ static int PORT = 5444; private static Socket socketToCommunicateWithClient; private static BufferedReader in; private static PrintWriter out; /** * Constructs a Server and starts it running. * * @param commandLineArguments Ignored here. */ public static void main(String[] commandLineArguments) { try { //------------------------------------------------------------------------------------- // KEY #1: Construct a ServerSocket that accepts connections from Clients. ServerSocket serverSocket = new ServerSocket(MainForServer.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. MainForServer.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. MainForServer.in = new BufferedReader(new InputStreamReader( MainForServer.socketToCommunicateWithClient.getInputStream())); //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- // KEY #4: From the Socket, construct a PrintWriter for writing to the Client. MainForServer.out = new PrintWriter( MainForServer.socketToCommunicateWithClient.getOutputStream(), true); //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- // 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 = MainForServer.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"); MainForServer.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. MainForServer.out.println(Integer.parseInt(dataFromClient) + numberFromUser); //----------------------------------------------------------------------------- } } catch (BindException exception) { System.out.println(exception); JOptionPane.showMessageDialog(null, "Server could not connect to port " + MainForServer.PORT + "\n" + "perhaps because that port is in use.\n\n"); } catch (SocketException exception) { System.out.println(exception); JOptionPane.showMessageDialog(null, "Server ended, either because it could not start" + " or (more likely) because the user closed the Client.\n\n"); } 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. See stack trace.\n\n"); JOptionPane.showMessageDialog(null, exception.getStackTrace()); } MainForServer.close(); } /** * Closes all resources that this Server uses: writer, reader, socket. */ private static void close() { Closeable[] resourcesToClose = {MainForServer.out, MainForServer.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 { MainForServer.socketToCommunicateWithClient.close(); } catch (Exception exception) { // Ignore; we made our best effort at closing the resource. } } }