@Override
 public void run() {
   try {
     ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
     // Get worker name
     // Modified the server to expect a username when the client first
     // connects. It passes the user who joined to a (unfinished)
     // onJoin callback
     String username = (String) in.readObject();
     onJoin(username);
     while (true) {
       Message msg = (Message) in.readObject();
       onNewMessage(socket, msg);
     }
   } catch (IOException e) {
     Log.e(
         TAG, String.format("Connection lost from client: %s", socket.getRemoteSocketAddress()));
     clients.remove(socket);
   } catch (ClassNotFoundException e) {
     Log.e(TAG, "Received invalid task from client.");
   } finally {
     try {
       socket.close();
     } catch (IOException e) {
       Log.e(TAG, "Unable to close connection");
     }
   }
 }
 private void onJoin(String username) {
   synchronized (clients) {
     for (Socket s : clients) {
       try {
         ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
         out.writeObject(new Message(username + " connected.", "Server"));
       } catch (IOException e) {
         Log.e(TAG, "Unable to send message to client.");
       }
     }
   }
 }
 @Override
 public void stopServer() {
   for (Socket s : clients) {
     if (s != null && !s.isClosed()) {
       try {
         s.close();
       } catch (IOException e) {
         Log.e(TAG, "Unable to close connection to client.");
       }
     }
   }
   mExecutor.shutdown();
 }
 @Override
 public void run() {
   try {
     ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
     while (true) {
       Message msg = (Message) in.readObject();
       onNewMessage(socket, msg);
     }
   } catch (IOException e) {
     Log.e(
         TAG, String.format("Connection lost from client: %s", socket.getRemoteSocketAddress()));
     clients.remove(socket);
   } catch (ClassNotFoundException e) {
     Log.e(TAG, "Received invalid task from client.");
   } finally {
     try {
       socket.close();
     } catch (IOException e) {
       Log.e(TAG, "Unable to close connection");
     }
   }
 }
 /**
  * Callback for when a message is received by the server. Notifies all clients about the new
  * message received
  *
  * @param from Socket where the new message originated
  * @param msg Message sent by the client
  */
 private void onNewMessage(Socket from, Message msg) {
   // Synchronize because we are iterating through all clients in a
   // thread
   synchronized (clients) {
     for (Socket s : clients) {
       try {
         ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
         out.writeObject(msg);
       } catch (IOException e) {
         Log.e(TAG, "Unable to send message to client.");
       }
     }
   }
 }
  @Override
  public void run() {
    try {
      ServerSocket serverSocket = null;
      try {
        serverSocket = new ServerSocket(port);
      } catch (IOException e) {
        Log.e(TAG, "Could not open server socket on port " + port + ".", e);
        return;
      }

      Log.i(TAG, "Listening for incoming commands on port " + port + ".");

      while (true) {
        try {
          Socket clientSocket = serverSocket.accept();
          Log.i(
              TAG,
              String.format(
                  "Got connection from %s:%s",
                  clientSocket.getRemoteSocketAddress(), clientSocket.getPort()));
          clients.add(clientSocket);
          mExecutor.execute(new ClientHandler(clientSocket));
        } catch (IOException e) {
          Log.e(TAG, "Error while listening for incoming connections.", e);
          break;
        }
      }

      Log.i(TAG, "Shutting down...");

      try {
        serverSocket.close();
      } catch (IOException e) {
        Log.e(TAG, "Unable to close connection");
        // Ignore because we're about to exit anyway.
      }
    } finally {
      mExecutor.shutdown();
    }
  }