title: Java SocketChannel not receiving incoming data properly
body: <p>I'm writing a chat room server which takes message from a chat client and broadcasts out the message to all users. This is an exercise from a book called <em>An Introduction to Network Programming with Java: Java 7 Compatible</em> with which I'm self-teaching Java networking basics. I wrote a GUI frontend for the chat room and implemented the server backend, following examples from the code in the book. However, when I tested the code with chat clients, the server seemed unable to receive clients' data. I can't figure out why. The code for the chat room (here it was made in command line mode for test purpose) and the client is as followings. Thank you.</p>
  
  <pre><code>// code for the server backend, problem seems to be lie in here.
  
  
   /**
   * The multiecho server itself
   */
  package channelEchoServer;
  
  import java.net.*;
  import java.io.*;
  import java.nio.*;
  import java.nio.channels.*;
  import java.util.*;
  
  public class MultiEchoServerNIO {
      private static ServerSocketChannel serverSocketChannel;
      private static final int PORT = 1234;
      private static Selector selector;
      private static Vector&lt;SocketChannel&gt; socketChannelVec;
      private static Vector&lt;ChatUser&gt; allUsers;
      public static final int CAPACITY = 20;
      public static final int BUFFER_SIZE = 2048;
      public static final String NEW_LINE = System.lineSeparator();
  
      public static void main(String[] args) {
          ServerSocket serverSocket = null;
          try {
              serverSocketChannel = ServerSocketChannel.open();
              serverSocketChannel.configureBlocking(false);
              serverSocket = serverSocketChannel.socket();
              InetSocketAddress netAddress = new InetSocketAddress(PORT);
              serverSocket.bind(netAddress);
              selector = Selector.open();
              serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
          }
          catch (IOException ioEx) {
              ioEx.printStackTrace();
              System.exit(1);
          }
          socketChannelVec = new Vector&lt;&gt;(CAPACITY);
          allUsers = new Vector&lt;&gt;(CAPACITY);
          System.out.println("Server is opened ...");
          processConnections();
      }
  
      private static void processConnections () {
          do {
              try {
                  int numKeys = selector.select();
                  System.out.println(numKeys + " keys selected.");
                  if (numKeys &gt; 0) {
                      Set eventKeys = selector.selectedKeys();
                      Iterator keyCycler = eventKeys.iterator();
                      while (keyCycler.hasNext()) {
                          SelectionKey key = (SelectionKey)keyCycler.next();
                          int keyOps = key.readyOps();
                          if ((keyOps &amp; SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
                              acceptConnection(key);
                              continue;
                          }
                          if ((keyOps &amp; SelectionKey.OP_READ) == SelectionKey.OP_READ) {
                              acceptData(key);
                          }
                      }
                  }
              }
              catch (IOException ioEx) {
                  ioEx.printStackTrace();
                  System.exit(1);
              }
          } while (true);
      }
      private static void acceptConnection (SelectionKey key) throws IOException {
          SocketChannel socketChannel;
          Socket socket;
  
          socketChannel = serverSocketChannel.accept();
          socketChannel.configureBlocking(false);
          socket = socketChannel.socket();
          System.out.println("Connection on " + socket + ".");
          socketChannel.register(selector, SelectionKey.OP_READ);
          socketChannelVec.add(socketChannel);
          selector.selectedKeys().remove(key);
      }
      private static void acceptData (SelectionKey key) throws IOException {
          SocketChannel socketChannel;
          Socket socket;
  
          ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
          socketChannel = (SocketChannel) key.channel();
          buffer.clear();
          int numBytes = socketChannel.read(buffer);
          socket = socketChannel.socket();
          if (numBytes == -1) {
              key.cancel();
              closeSocket(socket);
          }
          else {
              String chatName = null;
              byte[] byteArray = buffer.array();
              if (byteArray[0] == '#')
                  announceNewUser(socketChannel, buffer);
              else {
                  for (ChatUser chatUser : allUsers)
                      if (chatUser.getUserSocketChannel().equals(socketChannel))
                          chatName = chatUser.getChatName();
                  broadcastMessage(chatName, buffer);
              }
          }
      }
  
      private static void closeSocket (Socket socket) {
          try {
              if (socket != null)
                  socket.close();
          }
          catch (IOException ioEx) {
              System.out.println("Unable to close socket!");
          }
      }
      public static void announceNewUser (SocketChannel userSocketChannel, ByteBuffer buffer) {
          ChatUser chatUser;
          byte[] byteArray = buffer.array();
          int messageSize = buffer.position();
          String chatName = new String(byteArray, 1, messageSize);
          if (chatName.indexOf("\n") &gt;= 0)
              chatName = chatName.substring(0, chatName.indexOf("\n"));
          chatUser = new ChatUser(userSocketChannel, chatName);
          allUsers.add(chatUser);
          if (!socketChannelVec.remove(userSocketChannel)) {
              System.out.println("Can't find user!");
              return;
          } // we should save userSocketChannel in a chatUser instance before deleting it.
          chatName = chatUser.getChatName();
          System.out.println(chatName + " entered the chat room at " + new Date() +  "." + NEW_LINE);
          String welcomeMessage = "Welcome " + chatName + "!" + NEW_LINE;
          byte[] bytes = welcomeMessage.getBytes(); 
          buffer.clear();
          for (int i = 0; i &lt; welcomeMessage.length(); i++)
              buffer.put(bytes[i]);
          buffer.flip();
          try {
              chatUser.getUserSocketChannel().write(buffer);
          }
          catch (IOException ioEx) {
              ioEx.printStackTrace();
          }
      }
      public static void announceExit (String name) {
          System.out.println(name + " left chat room at " + new Date() + "." + NEW_LINE);
          for (ChatUser chatUser : allUsers) {
              if (chatUser.getChatName().equals(name))
                  allUsers.remove(chatUser);
          }
      }
      public static void broadcastMessage (String chatName, ByteBuffer buffer) {
          String messagePrefix = chatName + ": ";
          byte[] messagePrefixBytes = messagePrefix.getBytes();
          final byte[] CR = NEW_LINE.getBytes();
  
          try {
              int messageSize = buffer.position();
              byte[] messageBytes = buffer.array();
              byte[] messageBytesCopy = new byte[messageSize];
  
              String userMessage = new String(messageBytes, 0, messageSize);
              if (userMessage.equals("Bye"))
                  announceExit(chatName);
  
              for (int i = 0; i &lt; messageSize; i++) 
                  messageBytesCopy[i] = messageBytes[i];
              buffer.clear();
              buffer.put(messagePrefixBytes);
              for (int i = 0; i &lt; messageSize; i++)
                  buffer.put(messageBytesCopy[i]);
              buffer.put(CR);
              SocketChannel chatSocketChannel;
              for (ChatUser chatUser : allUsers) {
                  chatSocketChannel = chatUser.getUserSocketChannel();
                  buffer.flip();
                  chatSocketChannel.write(buffer);
              }
          }
          catch (IOException ioEx) {
              ioEx.printStackTrace();
          }
      }
  }
  
  class ChatUser {
      private SocketChannel userSocketChannel;
      private String chatName;
  
      public ChatUser (SocketChannel userSocketChannel, String chatName) {
          this.userSocketChannel = userSocketChannel;
          this.chatName = chatName;
      }
  
      public SocketChannel getUserSocketChannel () {
          return userSocketChannel;
      }
      public String getChatName () {
          return chatName;
      }
  }
  
  // Code for a chat client for testing purpose
      package multithreadEchoChatroomClientGUI;
  
  import java.awt.*;
  import java.awt.event.*;
  import javax.swing.*;
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  public class MultithreadEchoChatroomClient1 {
      private static Socket socket;
      private static InetAddress host;
      private static String address;
      public static final int PORT = 1234;
  
      public static void main(String[] args) {
  
          address = JOptionPane.showInputDialog("Enter the host name or IP address:");
          try {
              host = InetAddress.getByName(address);
          }
          catch (UnknownHostException uhEx) {
              JOptionPane.showMessageDialog(null, "Unknown Host!", "Error", JOptionPane.ERROR_MESSAGE);
              System.exit(1);
          }
          try {
              socket = new Socket(host, PORT);
          }
          catch (IOException ioEx) {
              JOptionPane.showMessageDialog(null, ioEx.toString(), "Error", JOptionPane.ERROR_MESSAGE);
              System.exit(1);
          }
  
          SwingUtilities.invokeLater(new Runnable () {
              public void run () {
                  ClientFrame client = new ClientFrame(host, socket, address);
                  client.setTitle("Chat");
                  client.setSize(400, 500);
                  client.setVisible(true);
                  new Thread(client).start();
              }
          });
      }
  }
  
  class ClientFrame extends JFrame implements Runnable {
      private InetAddress host;
      private String address;
      private Socket socket;
      private Scanner input;
      private PrintWriter output;
      private JMenuItem connect;
      private JTextArea serverResponseArea;
      private JTextArea messageArea;
      private JTextField messageFiled;
      private JButton sendButton;
      private String serverResponse;
      private String clientName;
  
      public ClientFrame (InetAddress host, Socket socket, String address) {
          this.host = host;
          this.socket = socket;
          this.address = address;
  
          initFrame();
      }
  
      public void run () {
  
          try {
              input = new Scanner(socket.getInputStream());
              output = new PrintWriter(socket.getOutputStream(), true);
          }
          catch (IOException ioEx) {
              JOptionPane.showMessageDialog(this, "Cannot create input or output stream!", "Error", JOptionPane.ERROR_MESSAGE);
              closeSocket();
              System.exit(1);
          }
  
          do {
              clientName = JOptionPane.showInputDialog("What nickname would you like to use in the chatroom?");
          } while (clientName == null);
          output.println("#" + clientName);
          do {
              serverResponse = input.nextLine();  
              serverResponseArea.append(serverResponse + "\n");
          } while (socket.isClosed() != true);
      }
  
      private final void closeSocket () {
          try {
              socket.close();
          }
          catch (IOException ioEx) {
              JOptionPane.showMessageDialog(this, "Cannot disconnect from chatroom!", "Error", JOptionPane.ERROR_MESSAGE);
          }
      }
  
      private void initFrame () {
          JMenuBar menuBar = createMenuBar();
          setJMenuBar(menuBar);
  
          JScrollPane responsePanel = createResponsePanel();
          add(responsePanel, BorderLayout.NORTH);
  
          JPanel messagePanel = createMessagePanel();
          add(messagePanel, BorderLayout.CENTER);
  
          //JPanel textPanel = createTextPanel();
          //add(textPanel, BorderLayout.SOUTH);
  
          addWindowListener(new WindowAdapter () {
              @Override
              public void windowClosing (WindowEvent we) {
                  if (!socket.isClosed())
                      closeSocket();
                  System.exit(0);
              }
          });
      }
  
      private JMenuBar createMenuBar () {
          JMenuBar menuBar = new JMenuBar();
          JMenu menu = new JMenu("Operations");
          connect = new JMenuItem("Connect");
          connect.setEnabled(false);
          connect.addActionListener(new ActionListener () {
              @Override
              public void actionPerformed (ActionEvent event) {
                  try {
                      host = InetAddress.getByName(address);
                  }
                  catch (UnknownHostException uhEx) {
                      JOptionPane.showMessageDialog(null, "Unknown Host!", "Error", JOptionPane.ERROR_MESSAGE);
                      System.exit(1);
                  }
                  try {
                      socket = new Socket(host, MultithreadEchoChatroomClient1.PORT);
                  }
                  catch (IOException ioEx) {
                      JOptionPane.showMessageDialog(null, ioEx.toString(), "Error", JOptionPane.ERROR_MESSAGE);
                  }
                  try {
                      input = new Scanner(socket.getInputStream());
                      output = new PrintWriter(socket.getOutputStream(), true);
                  }
                  catch (IOException ioEx) {
                      JOptionPane.showMessageDialog(ClientFrame.this, "Cannot create input or output stream!", "Error", JOptionPane.ERROR_MESSAGE);
                      closeSocket();
                      System.exit(1);
                  }
                  output.println("#" + clientName);
                  serverResponse = input.nextLine();
                  serverResponseArea.append(serverResponse + "\n");
              }
          });
          JMenuItem quit = new JMenuItem("Quit");
          quit.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed (ActionEvent event) {
                  if (!socket.isClosed())
                      closeSocket();
                  System.exit(0);
              }
          });
          menu.add(connect);
          menu.add(quit);
          menuBar.add(menu);
  
          return menuBar;
      }
  
      private JScrollPane createResponsePanel () {
          serverResponseArea = new JTextArea(20, 35);
          serverResponseArea.setEditable(false);
          serverResponseArea.setLineWrap(true);
          serverResponseArea.setWrapStyleWord(true);
          serverResponseArea.setMargin(new Insets(5, 5, 5, 5));
  
          JScrollPane scrlPane = new JScrollPane(serverResponseArea);
          scrlPane.setBorder(BorderFactory.createEmptyBorder(20, 10, 10, 20));
          scrlPane.setBackground(Color.yellow);
  
          return scrlPane;
      }
  
      private JPanel createMessagePanel () {
          JPanel msgPanel = new JPanel();
  
          msgPanel.setBorder(BorderFactory.createEmptyBorder(20,10, 10, 20));
          msgPanel.setBackground(Color.blue);
          msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.LINE_AXIS));
          JScrollPane srlPanel = createMessageTextPanel();
          msgPanel.add(srlPanel);
  
          JButton sdButton = createSendButton();
          msgPanel.add(sdButton);
  
          return msgPanel;
      }
  
      private JScrollPane createMessageTextPanel () {
          messageArea = new JTextArea(10, 35);
          //messageArea.setEditable(false);
          messageArea.setLineWrap(true);
          messageArea.setWrapStyleWord(true);
          messageArea.setMargin(new Insets(5, 5, 5, 5));
          JScrollPane mtPanel = new JScrollPane(messageArea);
  
          return mtPanel;
      }
  
      private JButton createSendButton () {
          JButton button = new JButton("Send");
          button.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed (ActionEvent event) {
                  String message;
  
                  message = messageArea.getText();
                  System.out.println(message);
                  output.println(message);
                  if (message.equals("Bye")) {
                      closeSocket();
                      connect.setEnabled(true);
                  }
                  messageArea.setText(""); 
                  //serverResponse = input.nextLine();
                  //serverResponseArea.append(serverResponse + "\n");
              }
          });
          return button;
      }
  } 
  </code></pre>
  
  <p>Thank you again for taking so much trouble reading much code and giving suggestions!</p>