title: Server Side EOFException
body: <p>I'm trying to write a messaging applicaton, and I'm able to send messages (shown as the server client displays the message correctly) but then kicks my client off of the server. The server prints the following error:</p>
  
  <blockquote>
    <p>java.io.EOFException  at
    java.io.ObjectInputStream$BlockDataInputStream.peekByte(UnknownSource)
    at java.io.ObjectInputStream.readObject0(Unknown Source)  at
    java.io.ObjectInputStream.readObject(Unknown Source)  at
    com.liftedstarfish.lifte.gpschat0_2.Server$ClientThread.run(Server.java:243)</p>
  </blockquote>
  
  <p>My Server Class:</p>
  
  <pre><code>public class Server {
      // a unique ID for each connection
      private static int uniqueId;
      // an ArrayList to keep the list of the Client
      private ArrayList&lt;ClientThread&gt; al;
      // if I am in a GUI
      private ServerGUI sg;
      // to display time
      private SimpleDateFormat sdf;
      // the port number to listen for connection
      private int port;
      // the boolean that will be turned of to stop the server
      private boolean keepGoing;
  
      private String name;
  
      /*
       *  server constructor that receive the port to listen to for connection as parameter
       *  in console
       */
      public Server(int port, String name) {
          this(port, name, null);
      }
  
      public Server(int port, String name, ServerGUI sg) {
          // GUI or not
          this.sg = sg;
          // the port
          this.port = port;
  
          this.name = name;
          // to display hh:mm:ss
          sdf = new SimpleDateFormat("HH:mm:ss");
          // ArrayList for the Client list
          al = new ArrayList&lt;ClientThread&gt;();
      }
  
      public void start() {
          keepGoing = true;
          /* create socket server and wait for connection requests */
          try 
          {
              // the socket used by the server
              ServerSocket serverSocket = new ServerSocket(port);
  
              // infinite loop to wait for connections
              while(keepGoing) 
              {
                  // format message saying we are waiting
                  display("Server waiting for Clients on " + name + ".");
  
                  Socket socket = serverSocket.accept();      // accept connection
                  // if I was asked to stop
                  if(!keepGoing)
                      break;
                  ClientThread t = new ClientThread(socket);  // make a thread of it
                  al.add(t);                                  // save it in the ArrayList
                  t.start();
              }
              // I was asked to stop
              try {
                  serverSocket.close();
                  for(int i = 0; i &lt; al.size(); ++i) {
                      ClientThread tc = al.get(i);
                      try {
                      tc.sInput.close();
                      tc.sOutput.close();
                      tc.socket.close();
                      }
                      catch(IOException ioE) {
                          // not much I can do
                      }
                  }
              }
              catch(Exception e) {
                  display("Exception closing the server and clients: " + e);
              }
          }
          // something went bad
          catch (IOException e) {
              String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + "\n";
              display(msg);
          }
      }       
      /*
       * For the GUI to stop the server
       */
      protected void stop() {
          keepGoing = false;
          // connect to myself as Client to exit statement 
          // Socket socket = serverSocket.accept();
          try {
              new Socket("localhost", port);
          }
          catch(Exception e) {
              // nothing I can really do
          }
      }
      /*
       * Display an event (not a message) to the console or the GUI
       */
      private void display(String msg) {
          String time = sdf.format(new Date()) + " " + msg;
          if(sg == null)
              System.out.println(time);
          else
              sg.appendEvent(time + "\n");
      }
      /*
       *  to broadcast a message to all Clients
       */
      private synchronized void broadcast(String message) {
          // add HH:mm:ss and \n to the message
          String time = sdf.format(new Date());
          String messageLf = time + " " + message + "\n";
          // display message on console or GUI
          if(sg == null)
              System.out.print(messageLf);
          else
              sg.appendRoom(messageLf);     // append in the room window
  
          // we loop in reverse order in case we would have to remove a Client
          // because it has disconnected
          for(int i = al.size(); --i &gt;= 0;) {
              ClientThread ct = al.get(i);
              // try to write to the Client if it fails remove it from the list
              if(!ct.writeMsg(messageLf)) {
                  al.remove(i);
                  display("Disconnected Client " + ct.username + " removed from list.");
              }
          }
      }
  
      // for a client who logoff using the LOGOUT message
      synchronized void remove(int id) {
          // scan the array list until we found the Id
          for(int i = 0; i &lt; al.size(); ++i) {
              ClientThread ct = al.get(i);
              // found it
              if(ct.id == id) {
                  al.remove(i);
                  return;
              }
          }
      }
  
      /*
       *  To run as a console application just open a console window and: 
       * &gt; java Server
       * &gt; java Server portNumber
       * If the port number is not specified 1500 is used
       */ 
      public static void main(String[] args) {
          // start server on port 1500 unless a PortNumber is specified 
          int portNumber = 1500;
          String serverName = "";
          switch(args.length) {
              case 1:
                  try {
                      portNumber = Integer.parseInt(args[0]);
                  }
                  catch(Exception e) {
                      System.out.println("Invalid port number.");
                      System.out.println("Usage is: &gt; java Server [portNumber]");
                      return;
                  }
              case 0:
                  break;
              default:
                  System.out.println("Usage is: &gt; java Server [portNumber]");
                  return;
  
          }
          // create a server object and start it
          Server server = new Server(portNumber, serverName);
          server.start();
      }
  
      public String getName()
      {
          return this.name;
      }
  
      /** One instance of this thread will run for each client */
      class ClientThread extends Thread {
          // the socket where to listen/talk
          Socket socket;
          ObjectInputStream sInput;
          ObjectOutputStream sOutput;
          // my unique id (easier for deconnection)
          int id;
          // the Username of the Client
          String username;
          // the only type of message a will receive
          ChatMessage cm;
          // the date I connect
          String date;
  
          // Constructore
          public ClientThread(Socket socket) {
              // a unique id
              id = ++uniqueId;
              this.socket = socket;
              /* Creating both Data Stream */
              System.out.println("Thread trying to create Object Input/Output Streams");
              try
              {
                  // create output first
                  sOutput = new ObjectOutputStream(socket.getOutputStream());
                  sInput  = new ObjectInputStream(socket.getInputStream());
                  // read the username
                  username = (String) sInput.readObject();
                  display(username + " just connected.");
              }
              catch (IOException e) {
                  display("Exception creating new Input/output Streams: " + e);
                  return;
              }
              // have to catch ClassNotFoundException
              // but I read a String, I am sure it will work
              catch (ClassNotFoundException e) {
              }
              date = new Date().toString() + "\n";
          }
  
          // what will run forever
          public void run() {
              // to loop until LOGOUT
              boolean keepGoing = true;
              while(keepGoing) {
                  // read a String (which is an object)
                  try {
                      //Location of Error
  &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;cm = (ChatMessage) sInput.readObject();&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
                  }
                  catch (IOException e) {
                      e.printStackTrace();
                      break;              
                  }
                  catch(ClassNotFoundException e2) {
                      e2.printStackTrace();
                      break;
                  }
                  // the messaage part of the ChatMessage
                  String message = cm.getMessage();
  
                  // Switch on the type of message receive
                  switch(cm.getType()) {
  
                  case ChatMessage.MESSAGE:
                      broadcast(username + ": " + message);
                      break;
                  case ChatMessage.LOGOUT:
                      display(username + " disconnected with a LOGOUT message.");
                      keepGoing = false;
                      break;
                  case ChatMessage.WHOISIN:
                      writeMsg("List of the users connected at " + sdf.format(new Date()) + "\n");
                      // scan al the users connected
                      for(int i = 0; i &lt; al.size(); ++i) {
                          ClientThread ct = al.get(i);
                          writeMsg((i+1) + ") " + ct.username + " since " + ct.date);
                      }
                      break;
                  case ChatMessage.ERROR:
                      broadcast(username + "&gt; " + message);
                      break;
                  }
              }
              // remove myself from the arrayList containing the list of the
              // connected Clients
              remove(id);
              close();
          }
  
          // try to close everything
          private void close() {
              // try to close the connection
              try {
                  if(sOutput != null) sOutput.close();
              }
              catch(Exception e) {}
              try {
                  if(sInput != null) sInput.close();
              }
              catch(Exception e) {};
              try {
                  if(socket != null) socket.close();
              }
              catch (Exception e) {}
          }
  
          /*
           * Write a String to the Client output stream
           */
          private boolean writeMsg(String msg) {
              // if Client is still connected send the message to it
              if(!socket.isConnected()) {
                  close();
                  return false;
              }
              // write the message to the stream
              try {
                  sOutput.writeObject(msg);
              }
              // if an error occurs, do not abort just inform the user
              catch(IOException e) {
                  display("Error sending message to " + username);
                  display(e.toString());
              }
              return true;
          }
      }
  }
  </code></pre>
  
  <p>ChatMessage Class:</p>
  
  <pre><code>public class ChatMessage extends AppCompatActivity implements Serializable {
  
      protected static final long serialVersionUID = 1112122200L;
  
      // The different types of message sent by the Client
      // WHOISIN to receive the list of the users connected
      // MESSAGE an ordinary message
      // LOGOUT to disconnect from the Server
      static final int WHOISIN = 0, MESSAGE = 1, LOGOUT = 2, ERROR = 3;
      private int type;
      private String message;
  
      // constructor
      public ChatMessage(int type, String message) {
          this.type = type;
          this.message = message;
      }
  
      @Override
      protected void onCreate(Bundle savedInstanceState)
      {
          super.onCreate(savedInstanceState);
  
          setContentView(R.layout.chat_message);
  
          final TextView lblMessage = (TextView) findViewById(R.id.text_view_message);
  
          if(type == MESSAGE)
              lblMessage.setText(message);
      }
  
      // getters
      public int getType() {
          return type;
      }
      public String getMessage() {
          return message;
      }
  }
  </code></pre>