it begins with the copyright statement attached to the code. The first example involves minor modifications of the original code. I have noted those changes in the body of the code. The second example involves more substantial modifications. I have noted those changes by a change in the copyright statement itself. Please follow this "standard" for the code you use in your final projects.
Conceptually, using the ServerSocket class is very simple.
/* * Cay S. Horstmann & Gary Cornell, Core Java * Published By Sun Microsystems Press/Prentice-Hall * Copyright (C) 1997 Sun Microsystems Inc. * All Rights Reserved. * * Permission to use, copy, modify, and distribute this * software and its documentation for NON-COMMERCIAL purposes * and without fee is hereby granted provided that this * copyright notice appears in all copies. */ /* * * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. */ /** * @version 1.10 27 Jun 1997 * @author Cay Horstmann */ /* *Some modifications have been made to this code by Jerrold Siegel. *These modifications are noted as comments in the code itself. *The modifications have been make in compliance with the original *Copyright statement above. *THE AUTHOR OF THESE CHANGES ALSO ASSERTS THE ORIGINAL AUTHOR'S POSITION *AS TO THE LACK OF REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE. */ import java.io.*; import java.net.*; public class ThreadedEchoServer //J. Siegel: java ThreadedEchoServer is invoked on, say jinx.umsl.edu { public static void main(String[] args ) { int i = 1; int port_to_listen=8189;//J. Siegel: Use a symbolic reference for the port try { ServerSocket s = new ServerSocket(port_to_listen); //J. Siegel: Acknowledge that the Server is listening. System.out.println("Listening on Port "+port_to_listen); for (;;) { Socket incoming = s.accept( ); System.out.println("Spawning " + i); new ThreadedEchoHandler(incoming, i).start(); i++; } } catch (Exception e) { System.out.println(e); } } } class ThreadedEchoHandler extends Thread { private Socket incoming; private int counter; public ThreadedEchoHandler(Socket i, int c) { incoming = i; counter = c; } public void run() { try { BufferedReader in = new BufferedReader (new InputStreamReader(incoming.getInputStream())); PrintWriter out = new PrintWriter (incoming.getOutputStream(), true /* autoFlush */); out.println( "Hello! Enter BYE to exit." ); boolean done = false; while (!done) { String str = in.readLine(); if (str == null) done = true; else { out.println("Echo (" + counter + "): " + str); if (str.trim().equals("BYE")) done = true; } } incoming.close(); } catch (Exception e) { System.out.println(e); } } }
The next example, based on ThreadedEchoServer.java, provides a simple "Chat" server. The code works under the assumption that only two users connect to the chat-server.
/* * Cay S. Horstmann & Gary Cornell, Core Java * Published By Sun Microsystems Press/Prentice-Hall * Copyright (C) 1997 Sun Microsystems Inc. * All Rights Reserved. * * Permission to use, copy, modify, and distribute this * software and its documentation for NON-COMMERCIAL purposes * and without fee is hereby granted provided that this * copyright notice appears in all copies. * * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. */ /** * @version 1.10 27 Jun 1997 * @author Cay Horstmann */ /* *This code has been modified by Jerrold Siegel. *The modifications have been make in compliance with the original *Copyright statement above. *THE AUTHOR OF THESE MODIFICATIONS ALSO ASSERTS THE ORIGINAL AUTHOR'S POSITION *AS TO THE LACK OF REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE. */ import java.io.*; import java.net.*; public class ThreadedChatServer { public static void main(String[] args ) { int i = 0; int port_to_listen_on=8189; BufferedReader in[]=new BufferedReader[2]; PrintWriter out[]=new PrintWriter[2]; //Two "global" channels are required to cross-connect the two ThreadedChatHandler instances. try { ServerSocket s = new ServerSocket(port_to_listen_on); System.out.println("Listening on Port "+port_to_listen_on); for (;;) { Socket incoming = s.accept( ); System.out.println("Spawning " + i); //must pass "in" and "out" since we are not using inner classes. new ThreadedChatHandler(incoming, i,in,out).start(); i++; } } catch (Exception e) { System.out.println(e); } } } class ThreadedChatHandler extends Thread { private Socket incoming; private int counter; private BufferedReader in[]; private PrintWriter out[]; public ThreadedChatHandler(Socket i, int c,BufferedReader in[],PrintWriter out []) { incoming = i; counter = c; this.in=in;this.out=out; } public void run() { int other=(counter==0)?1:0; String str[]=new String[2]; try { in[counter] = new BufferedReader (new InputStreamReader(incoming.getInputStream())); out[counter] = new PrintWriter (incoming.getOutputStream(), true /* autoFlush */); out[counter].println( "Hello! Enter BYE to exit." ); boolean done = false; while (!done) { str[other] = in[counter].readLine(); if (str[other] == null) done = true; else { out[other].println("Echo (" + counter + "): " + str[other]); if (str[other].trim().equals("BYE")) done = true; } } incoming.close(); } catch (Exception e) { System.out.println(e); } } }