title: Android TCP Connection (Multiple Client)
body: <p>I use <a href="http://myandroidsolutions.blogspot.ro/2013/03/android-tcp-connection-enhanced.html" rel="noreferrer">this (Android TCP Connection Enhanced)</a> tutorial to create simple JAVA TCPServer ana Android TCPClient. It works perfect, but with this code i can connect only one device to the server at the same time. What do I have to change to connect with several devices?</p>
  
  <h2>JAVA Server:   Constants</h2>
  
  <pre class="lang-java prettyprint-override"><code>public class Constants {
  
      public static final String CLOSED_CONNECTION = "kazy_closed_connection";
      public static final String LOGIN_NAME = "kazy_login_name";
  
  }
  </code></pre>
  
  <h2>JAVA Server:   MainScreen</h2>
  
  <pre class="lang-java prettyprint-override"><code>public class MainScreen extends JFrame {
  
      /**
       * 
       */
      private static final long serialVersionUID = 8399514248326995812L;
      private JTextArea messagesArea;
      private JButton sendButton;
      private JTextField message;
      private JButton startServer;
      private JButton stopServer;
      private TcpServer mServer;
  
      public MainScreen() {
  
          super("MainScreen");
  
          JPanel panelFields = new JPanel();
          panelFields.setLayout(new BoxLayout(panelFields, BoxLayout.X_AXIS));
  
          JPanel panelFields2 = new JPanel();
          panelFields2.setLayout(new BoxLayout(panelFields2, BoxLayout.X_AXIS));
  
          // here we will have the text messages screen
          messagesArea = new JTextArea();
          messagesArea.setColumns(30);
          messagesArea.setRows(10);
          messagesArea.setEditable(false);
  
          sendButton = new JButton("Send");
          sendButton.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
                  // get the message from the text view
                  String messageText = message.getText();
                  // add message to the message area
                  messagesArea.append("\n" + messageText);
                  if (mServer != null) {
                      // send the message to the client
                      mServer.sendMessage(messageText);
                  }
                  // clear text
                  message.setText("");
              }
          });
  
          startServer = new JButton("Start");
          startServer.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
  
                  // creates the object OnMessageReceived asked by the TCPServer
                  // constructor
                  mServer = new TcpServer(new TcpServer.OnMessageReceived() {
                      @Override
                      // this method declared in the interface from TCPServer
                      // class is implemented here
                      // this method is actually a callback method, because it
                      // will run every time when it will be called from
                      // TCPServer class (at while)
                      public void messageReceived(String message) {
                          messagesArea.append("\n " + message);
                      }
                  });
                  mServer.start();
  
                  // disable the start button and enable the stop one
                  startServer.setEnabled(false);
                  stopServer.setEnabled(true);
  
              }
          });
  
          stopServer = new JButton("Stop");
          stopServer.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent e) {
  
                  if (mServer != null) {
                      mServer.close();
                  }
  
                  // disable the stop button and enable the start one
                  startServer.setEnabled(true);
                  stopServer.setEnabled(false);
  
              }
          });
  
          // the box where the user enters the text (EditText is called in
          // Android)
          message = new JTextField();
          message.setSize(200, 20);
  
          // add the buttons and the text fields to the panel
          panelFields.add(messagesArea);
          panelFields.add(startServer);
          panelFields.add(stopServer);
  
          panelFields2.add(message);
          panelFields2.add(sendButton);
  
          getContentPane().add(panelFields);
          getContentPane().add(panelFields2);
  
          getContentPane().setLayout(
                  new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
  
          setSize(300, 170);
          setVisible(true);
      }
  
  }
  </code></pre>
  
  <h2>JAVA Server:   TcpServer</h2>
  
  <pre class="lang-java prettyprint-override"><code>public class TcpServer extends Thread {
  
      public static final int SERVERPORT = 4444;
      // while this is true the server will run
      private boolean running = false;
      // used to send messages
      private PrintWriter bufferSender;
      // callback used to notify new messages received
      private OnMessageReceived messageListener;
      private ServerSocket serverSocket;
      private Socket client;
  
      /**
       * Constructor of the class
       * 
       * @param messageListener
       *            listens for the messages
       */
      public TcpServer(OnMessageReceived messageListener) {
          this.messageListener = messageListener;
      }
  
      public static void main(String[] args) {
  
          // opens the window where the messages will be received and sent
          MainScreen frame = new MainScreen();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.pack();
          frame.setVisible(true);
  
      }
  
      /**
       * Close the server
       */
      public void close() {
  
          running = false;
  
          if (bufferSender != null) {
              bufferSender.flush();
              bufferSender.close();
              bufferSender = null;
          }
  
          try {
              client.close();
              serverSocket.close();
          } catch (Exception e) {
              e.printStackTrace();
          }
  
          System.out.println("S: Done.");
          serverSocket = null;
          client = null;
  
      }
  
      /**
       * Method to send the messages from server to client
       * 
       * @param message
       *            the message sent by the server
       */
      public void sendMessage(String message) {
          if (bufferSender != null &amp;&amp; !bufferSender.checkError()) {
              bufferSender.println(message);
              bufferSender.flush();
          }
      }
  
      public boolean hasCommand(String message) {
          if (message != null) {
              if (message.contains(Constants.CLOSED_CONNECTION)) {
                  messageListener.messageReceived(message.replaceAll(
                          Constants.CLOSED_CONNECTION, "")
                          + " disconnected");
                  // close the server connection if we have this command and
                  // rebuild a new one
                  close();
                  runServer();
                  return true;
              } else if (message.contains(Constants.LOGIN_NAME)) {
                  messageListener.messageReceived(message.replaceAll(
                          Constants.LOGIN_NAME, "") + " connected");
                  return true;
              }
          }
  
          return false;
      }
  
      /**
       * Builds a new server connection
       */
      private void runServer() {
          running = true;
  
          try {
              System.out.println("S: Connecting...");
  
              // create a server socket. A server socket waits for requests to
              // come in over the network.
              serverSocket = new ServerSocket(SERVERPORT);
  
              // create client socket... the method accept() listens for a
              // connection to be made to this socket and accepts it.
              client = serverSocket.accept();
  
              System.out.println("S: Receiving...");
  
              try {
  
                  // sends the message to the client
                  bufferSender = new PrintWriter(new BufferedWriter(
                          new OutputStreamWriter(client.getOutputStream())), true);
  
                  // read the message received from client
                  BufferedReader in = new BufferedReader(new InputStreamReader(
                          client.getInputStream()));
  
                  // in this while we wait to receive messages from client (it's
                  // an infinite loop)
                  // this while it's like a listener for messages
                  while (running) {
  
                      String message = null;
                      try {
                          message = in.readLine();
                      } catch (IOException e) {
                          System.out.println("Error reading message: "
                                  + e.getMessage());
                      }
  
                      if (hasCommand(message)) {
                          continue;
                      }
  
                      if (message != null &amp;&amp; messageListener != null) {
                          // call the method messageReceived from ServerBoard
                          // class
                          messageListener.messageReceived(message);
                      }
                  }
  
              } catch (Exception e) {
                  System.out.println("S: Error");
                  e.printStackTrace();
              }
  
          } catch (Exception e) {
              System.out.println("S: Error");
              e.printStackTrace();
          }
      }
  
      @Override
      public void run() {
          super.run();
  
          runServer();
  
      }
  
      // Declare the interface. The method messageReceived(String message) will
      // must be implemented in the ServerBoard
      // class at on startServer button click
      public interface OnMessageReceived {
          public void messageReceived(String message);
      }
  
  }
  </code></pre>
  
  <h2>Android Client:   TCPClient</h2>
  
  <pre class="lang-java prettyprint-override"><code>public class TCPClient {
  
      public static final String SERVER_IP = "192.168.0.102"; // your computer IP
                                                              // address
      public static final int SERVER_PORT = 4444;
      // message to send to the server
      private String mServerMessage;
      // sends message received notifications
      private OnMessageReceived mMessageListener = null;
      // while this is true, the server will continue running
      private boolean mRun = false;
      // used to send messages
      private PrintWriter mBufferOut;
      // used to read messages from the server
      private BufferedReader mBufferIn;
  
      private String uid;
  
      /**
       * Constructor of the class. OnMessagedReceived listens for the messages
       * received from server
       */
      public TCPClient(OnMessageReceived listener) {
          mMessageListener = listener;
      }
  
      /**
       * Sends the message entered by client to the server
       * 
       * @param message
       *            text entered by client
       */
      public void sendMessage(String message) {
          if (mBufferOut != null &amp;&amp; !mBufferOut.checkError()) {
              mBufferOut.println(message);
              mBufferOut.flush();
          }
      }
  
      /**
       * Close the connection and release the members
       */
      public void stopClient() {
  
          // send mesage that we are closing the connection
          TelephonyManager tManager = (TelephonyManager) MyApplication.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
          uid = tManager.getDeviceId();
          sendMessage(Constants.CLOSED_CONNECTION + "id: " + uid);
  
          mRun = false;
  
          if (mBufferOut != null) {
              mBufferOut.flush();
              mBufferOut.close();
          }
  
          mMessageListener = null;
          mBufferIn = null;
          mBufferOut = null;
          mServerMessage = null;
      }
  
      public void run() {
  
          mRun = true;
  
          try {
              // here you must put your computer's IP address.
              InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
  
              MyLog.e("TCP Client", "C: Connecting...");
  
              // create a socket to make the connection with the server
              Socket socket = new Socket(serverAddr, SERVER_PORT);
  
              try {
  
                  // sends the message to the server
                  mBufferOut = new PrintWriter(new BufferedWriter(
                          new OutputStreamWriter(socket.getOutputStream())), true);
  
                  // receives the message which the server sends back
                  mBufferIn = new BufferedReader(new InputStreamReader(
                          socket.getInputStream()));
                  // send login name
                  TelephonyManager tManager = (TelephonyManager) MyApplication.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
                  uid = tManager.getDeviceId();
                  sendMessage(Constants.LOGIN_NAME + "id: " + uid);
  
                  // in this while the client listens for the messages sent by the
                  // server
                  while (mRun) {
  
                      mServerMessage = mBufferIn.readLine();
  
                      if (mServerMessage != null &amp;&amp; mMessageListener != null) {
                          // call the method messageReceived from MyActivity class
                          mMessageListener.messageReceived(mServerMessage);
                      }
  
                  }
  
                  MyLog.e("RESPONSE FROM SERVER", "S: Received Message: '"
                          + mServerMessage + "'");
  
              } catch (Exception e) {
  
                  MyLog.e("TCP", "S: Error", e);
  
              } finally {
                  // the socket must be closed. It is not possible to reconnect to
                  // this socket
                  // after it is closed, which means a new socket instance has to
                  // be created.
                  socket.close();
              }
  
          } catch (Exception e) {
  
              MyLog.e("TCP", "C: Error", e);
  
          }
  
      }
  
      // Declare the interface. The method messageReceived(String message) will
      // must be implemented in the MyActivity
      // class at on asynckTask doInBackground
      public interface OnMessageReceived {
          public void messageReceived(String message);
      }
  }
  </code></pre>
  
  <h2>Android Client:   Constants</h2>
  
  <pre class="lang-java prettyprint-override"><code>public class Constants {
  
      public static final String CLOSED_CONNECTION = "kazy_closed_connection";
      public static final String LOGIN_NAME = "kazy_login_name";
  
  }
  </code></pre>
  
  <h2>Android Client:  My Activity</h2>
  
  <pre class="lang-java prettyprint-override"><code>@Override
  protected void onPause() {
      super.onPause();
      if(connect != null) {
          connect.cancel(true);
      }
      if(mTcpClient != null) {
          MyLog.d(TAG, "stopClient");
          mTcpClient.stopClient();
          mTcpClient = null;
      }
  }
  
  public class ConnectTask extends AsyncTask&lt;String,String,TCPClient&gt; {
  
      @Override
      protected TCPClient doInBackground(String... message) {
  
          MyLog.d(TAG, "doInBackground");
  
          //we create a TCPClient object and
          mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
              @Override
              //here the messageReceived method is implemented
              public void messageReceived(String message) {
  
                  //this method calls the onProgressUpdate
                  publishProgress(message);
  
              }
          });
          mTcpClient.run();
  
          return null;
      }
  
      @Override
      protected void onProgressUpdate(String... values) {
          super.onProgressUpdate(values);
          MyLog.d(TAG, "onProgressUpdate");
          View view = adapter.getChildView(0, 0, false, null, null);
          TextView text = (TextView) view.findViewById(R.id.betChildOdd);
          child2.get(0).get(0).put("OLD", text.getText().toString());
          child2.get(0).get(0).put(CONVERTED_ODDS, values[0].toString());
          child2.get(0).get(0).put("CHANGE", "TRUE");
          adapter.notifyDataSetChanged();
      }
  }
  </code></pre>