Coverage Report - net.mtu.eggplant.util.network.TCPServer
 
Classes in this File Line Coverage Branch Coverage Complexity
TCPServer
0%
0/79
0%
0/22
3.4
 
 1  
 /*
 2  
  * Copyright (c) 2000
 3  
  *      Jon Schewe.  All rights reserved
 4  
  *
 5  
  * Redistribution and use in source and binary forms, with or without
 6  
  * modification, are permitted provided that the following conditions
 7  
  * are met:
 8  
  * 1. Redistributions of source code must retain the above copyright
 9  
  *    notice, this list of conditions and the following disclaimer.
 10  
  * 2. Redistributions in binary form must reproduce the above copyright
 11  
  *    notice, this list of conditions and the following disclaimer in the
 12  
  *    documentation and/or other materials provided with the distribution.
 13  
  *
 14  
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 15  
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 16  
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 17  
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 18  
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 19  
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 20  
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 21  
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 22  
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 23  
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 24  
  * SUCH DAMAGE.
 25  
  *
 26  
  * I'd appreciate comments/suggestions on the code jpschewe@mtu.net
 27  
  */
 28  
 package net.mtu.eggplant.util.network;
 29  
 
 30  
 import java.io.BufferedReader;
 31  
 import java.io.IOException;
 32  
 import java.io.InputStreamReader;
 33  
 import java.io.PrintWriter;
 34  
 import java.net.ServerSocket;
 35  
 import java.net.Socket;
 36  
 
 37  
 import org.slf4j.Logger;
 38  
 import org.slf4j.LoggerFactory;
 39  
 
 40  
 /**
 41  
  * Simple TCP echo server.
 42  
  * 
 43  
  * @version $Revision$
 44  
  */
 45  
 public class TCPServer extends Object implements
 46  
                                      Runnable,
 47  
                                      Cloneable {
 48  
 
 49  0
   private static final Logger LOGGER = LoggerFactory.getLogger(TCPServer.class);
 50  
 
 51  
   public static final int DEFAULT_PORT = 6789;
 52  
 
 53  
   private int _port;
 54  
 
 55  
   private ServerSocket _listenSocket;
 56  
 
 57  0
   private Socket _clientSocket = null;
 58  
 
 59  0
   private BufferedReader _input = null;
 60  
 
 61  0
   private PrintWriter _output = null;
 62  
 
 63  
   /**
 64  
    * default constructor. Uses port 6789 as the port to listen on.
 65  
    **/
 66  
   public TCPServer() {
 67  0
     this(DEFAULT_PORT);
 68  0
   }
 69  
 
 70  
   /**
 71  
    * Create a ServerSocket to listen for connections on If port < 0 or port >
 72  
    * 65535 port defaults to DEFAULT_PORT.
 73  
    * 
 74  
    * @param port
 75  
    *          the port to listen on
 76  
    **/
 77  0
   public TCPServer(final int port) {
 78  0
     if (port < 0 || port > 65535) {
 79  0
       _port = DEFAULT_PORT;
 80  
     } else {
 81  0
       _port = port;
 82  
     }
 83  
 
 84  
     try {
 85  0
       _listenSocket = new ServerSocket(_port);
 86  0
     } catch (final IOException e) {
 87  0
       LOGGER.error("Exception creating server socket", e);
 88  0
     }
 89  0
     LOGGER.error("Server: listening on port " + _port);
 90  0
   }
 91  
 
 92  
   /**
 93  
    * The body of the server thread. Loop forever, listening for and accepting
 94  
    * connections from clients. For each connection, create a clone that executes
 95  
    * {@link #initializeConnection()}.
 96  
    **/
 97  
   public void run() {
 98  
     // check if we're starting fresh or already have a connection
 99  0
     if (_clientSocket != null) {
 100  0
       initializeConnection();
 101  
     }
 102  
 
 103  
     try {
 104  
       while (true) {
 105  0
         Socket clientSocket = _listenSocket.accept();
 106  
         try {
 107  0
           final TCPServer clone = (TCPServer) this.clone();
 108  0
           clone.setSocket(clientSocket);
 109  0
           final ThreadGroup tg = new ThreadGroup(clientSocket.getInetAddress()
 110  
               .getHostName());
 111  0
           Thread t = new Thread(tg, clone);
 112  0
           t.start();
 113  0
         } catch (final CloneNotSupportedException cnse) {
 114  0
           LOGGER.error("Clone Not supported?!");
 115  0
         }
 116  0
       }
 117  0
     } catch (final IOException e) {
 118  0
       LOGGER.error("Exception while listening for connections", e);
 119  
     }
 120  0
   }
 121  
 
 122  
   /**
 123  
    * Actually make the connection and wait for data. Just echo data back on the
 124  
    * socket.
 125  
    */
 126  
   public void initializeConnection() {
 127  
     try {
 128  0
       _input = new BufferedReader(new InputStreamReader(getSocket()
 129  
           .getInputStream()));
 130  
 
 131  0
       _output = new PrintWriter(getSocket().getOutputStream(), true);
 132  0
     } catch (final IOException e) {
 133  
       try {
 134  0
         getSocket().close();
 135  0
       } catch (final IOException e2) {
 136  0
         if (LOGGER.isDebugEnabled()) {
 137  0
           LOGGER.debug(e2.getMessage(), e2);
 138  
         }
 139  0
       }
 140  0
       LOGGER.error("Exception while getting socket streams: " + e);
 141  0
       return;
 142  0
     }
 143  
 
 144  
     // wait for data
 145  
     String line;
 146  
     try {
 147  
       while (true) {
 148  
         // read in a line
 149  0
         line = readLine();
 150  0
         if (processData(line)) {
 151  0
           break;
 152  
         }
 153  
       }
 154  0
     } catch (final IOException e) {
 155  0
       if (LOGGER.isDebugEnabled()) {
 156  0
         LOGGER.debug(e.getMessage(), e);
 157  
       }
 158  
     } finally {
 159  0
       try {
 160  0
         getSocket().close();
 161  0
       } catch (final IOException e2) {
 162  0
         if (LOGGER.isDebugEnabled()) {
 163  0
           LOGGER.debug(e2.getMessage(), e2);
 164  
         }
 165  0
       }
 166  0
     }
 167  
 
 168  0
   }
 169  
 
 170  
   /**
 171  
    * do something with a line of input. Just print the line back out on the
 172  
    * socket. Override this to do more with the data.
 173  
    * 
 174  
    * @param line
 175  
    *          the input
 176  
    * @return true if we should quit, false otherwise
 177  
    **/
 178  
   protected boolean processData(final String line) {
 179  0
     if (line.equals("Quit")) {
 180  0
       return true;
 181  
     } else {
 182  0
       print(line);
 183  
     }
 184  0
     return false;
 185  
   }
 186  
 
 187  
   /**
 188  
    * print something to the socket.
 189  
    * 
 190  
    * @param message
 191  
    *          the message, if not connected nothing happens
 192  
    **/
 193  
   public void print(final String message) {
 194  0
     if (_output != null) {
 195  0
       _output.println(getClass().getName() + ": " + message);
 196  
     }
 197  0
   }
 198  
 
 199  
   /**
 200  
    * read a line from the socket
 201  
    * 
 202  
    * @return the line, null if not connected
 203  
    **/
 204  
   public String readLine() throws IOException {
 205  0
     if (_input != null) {
 206  0
       return _input.readLine();
 207  
     } else {
 208  0
       return null;
 209  
     }
 210  
   }
 211  
 
 212  
   /**
 213  
    * get the actual socket
 214  
    * 
 215  
    * @return the socket, null if not connected
 216  
    **/
 217  
   protected Socket getSocket() {
 218  0
     return _clientSocket;
 219  
   }
 220  
 
 221  
   /**
 222  
    * set the actual socket.
 223  
    * 
 224  
    * @param s
 225  
    *          the socket
 226  
    **/
 227  
   protected void setSocket(final Socket s) {
 228  0
     _clientSocket = s;
 229  0
   }
 230  
 
 231  
   public static void main(final String[] args) {
 232  
     TCPServer server;
 233  0
     if (args.length == 1) {
 234  
       try {
 235  0
         server = new TCPServer(Integer.parseInt(args[0]));
 236  0
       } catch (final NumberFormatException e) {
 237  0
         LOGGER.warn("Could not parse " + args[0]
 238  
             + " as a number, falling back to default port of " + DEFAULT_PORT);
 239  0
         server = new TCPServer();
 240  0
       }
 241  
     } else {
 242  0
       server = new TCPServer();
 243  
     }
 244  0
     final Thread t = new Thread(server);
 245  0
     t.start();
 246  0
   }
 247  
 }