title: Android NIO Server Selectors Reading When no message is sent
body: <p>I'm trying to use a NIO server to read/write to a client for TCP connections.  I've made a successful connection, and my initial message is sent to the server and correctly processed.  It says that the server is sending a message back, but I'm not receiving any input on the client side.  Also, after the server sends a message back, the application crashes saying that it was trying to read a null pointer (Line 127 server code). </p>
  
  <p>It's important to note that I'm new to this concept and I don't really understand selectors.  I've looked at tutorials, but contradictary messages have led me to be even more confused on the issue.  If anyone has any good tutorials on this topic I'd be greatly appreciative. </p>
  
  <p>Here's my code.  </p>
  
  <p>Client Main Activity Screen</p>
  
  <pre><code>package com.example.client;
  
  import android.app.Activity;
  import android.app.AlertDialog;
  import android.content.Intent;
  import android.os.Bundle;
  import android.os.Handler;
  import android.os.Message;
  import android.view.Menu;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.widget.Button;
  import android.widget.EditText;
  import android.widget.TextView;
  
  import com.example.client.ServerService.Connect;
  
  
  
  public class MainActivity extends Activity {
  
      Button button;
      TextView textView;
      EditText editText;
      EditText editTextps;
      static Handler handler;
      Connect connect=null;
      Object myLock=new Object();
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          button=(Button) findViewById(R.id.button1);
          textView=(TextView) findViewById(R.id.textView1);
          editText=(EditText) findViewById(R.id.editText1);
          editTextps=(EditText) findViewById(R.id.editText2);
          handler=new Handler(){
              @Override
              public void handleMessage(Message msg) { //Handle code for receiving messages 
                  super.handleMessage(msg);//when a message is received it's input is processed here
                  Bundle bundle=msg.getData();
                  if(bundle.getInt("int") == 2){
                      if(bundle.getInt("valid") == 1){
                          Intent i = new Intent();
                          i.setClassName("com.example.client",
                                  "com.example.client.ReadyScreen");
                          startActivity(i);
                      }else{
                          alertMessage(); 
                          editText.setText("");
                          editTextps.setText("");
                      }
                  }
              }
  
          };
  
          startService(new Intent(getBaseContext(), ServerService.class));
  
  
          button.setOnClickListener(new OnClickListener() {
              @Override
              public void onClick(View arg0) {
                  String str=editText.getText().toString();
                  String strps=editTextps.getText().toString();
                  Message msg=Message.obtain();
                  Bundle bundle=new Bundle();
                  bundle.putString("name", str);
                  bundle.putString("password", strps);
                  msg.setData(bundle);
                  ServerService.threadHandler.sendMessage(msg);
              }
          });
      }
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          getMenuInflater().inflate(R.menu.main, menu);
          return true;
      }
  
      public void alertMessage() {
  
          final android.app.AlertDialog.Builder show = new AlertDialog.Builder(this).setTitle("Error").setMessage("Wrong username/password").setNeutralButton("close", null);
          show.show();
      }
  }
  </code></pre>
  
  <p>Server Service where I'm running the connection and IO</p>
  
  <pre><code>package com.example.client;
  
  import java.net.InetSocketAddress;
  import java.net.SocketAddress;
  import java.nio.ByteBuffer;
  import java.nio.channels.SelectionKey;
  import java.nio.channels.Selector;
  import java.nio.channels.SocketChannel;
  
  import android.app.Service;
  import android.content.Intent;
  import android.os.Handler;
  import android.os.IBinder;
  import android.os.Looper;
  import android.os.Message;
  import android.util.Log;
  import android.widget.Toast;
  
  public class ServerService extends Service {
  
      Handler handler;
      static MyHandle threadHandler;
      Connect connect=null;
      Object myLock=new Object();
      static SocketChannel socketChannel=null;
      public ByteBuffer sendBuffer=ByteBuffer.allocate(1024);
      static ByteBuffer receiveBuffer=ByteBuffer.allocate(1024);
      static Selector selector;
      private static final String TAG = ServerService.class.getSimpleName();
  
      @Override
      public IBinder onBind(Intent intent) {
          return null;
      }
  
      @Override
      public int onStartCommand(Intent intent, int flags, int startId){
          Log.d(TAG, "Started running the service");
          System.out.println(TAG + "Started running the service");
  
          (new Thread(new ReceivingThread())).start();
          (new Thread(new SendingThread())).start();
  
          return START_STICKY;
      }
  
  
      @Override 
      public void onDestroy(){
          super.onDestroy();
          Toast.makeText(this, "Service Stopped", Toast.LENGTH_LONG).show();  
      }
  
      class Connect {
          SocketChannel socketChannel=null;
          public ByteBuffer sendBuffer=ByteBuffer.allocate(1024);
          ByteBuffer receiveBuffer=ByteBuffer.allocate(1024);
          Selector selector;
          public Connect() {
  
              try {
                  socketChannel=SocketChannel.open();
                  SocketAddress remoteAddress=new InetSocketAddress("192.168.2.17", 20001);
                  socketChannel.connect(remoteAddress);
                  socketChannel.configureBlocking(false);
                  selector=Selector.open();
                  socketChannel.register(selector, SelectionKey.OP_READ);
              } catch (Exception e) {
  
                  e.printStackTrace();
              }
          }
      }
  
      public class ReceivingThread implements Runnable{
  
          @Override
          public void run() {
              Log.d(TAG, "Started running the receive thread");
              connect=new Connect();
              try {
                  while(true){
                      if(connect.selector.select()==0)
                          continue;
                      Play receivedMessage = new Play();
                      receivedMessage.play();
                  }
              } catch (Exception e) {
                  e.printStackTrace();
                  System.out.println(e.getMessage());
              }
          }
  
      }
  
      public class SendingThread implements Runnable{
  
          @Override
          public void run() {
              Log.d(TAG, "Started running the send thread");
              Looper.prepare();
              threadHandler=new MyHandle(Looper.myLooper());
              Looper.loop();
          }
  
      }
  
      class MyHandle extends Handler{  
          public MyHandle(){
          }
          public MyHandle(Looper looper){ 
                      super(looper);
          }
          public void handleMessage(Message msg){
              String str=msg.getData().getString("name");
              String strps=msg.getData().getString("password");
              MyMessage message=new MyMessage();
              message.setb((byte)1);
              message.setUsername(str);
              message.setPassword(strps);
              try {
                  connect.sendBuffer.clear();
                  connect.sendBuffer.put(message.Message2Byte());
                  connect.sendBuffer.flip();
                  connect.socketChannel.write(connect.sendBuffer);
              } catch (Exception e) {
  
                  e.printStackTrace();
              }
          }
      }
  
  }
  </code></pre>
  
  <p>The Server Code</p>
  
  <pre><code>package mytcp;
  
  import java.io.IOException;
  import java.net.InetSocketAddress;
  import java.nio.ByteBuffer;
  import java.nio.channels.SelectionKey;
  import java.nio.channels.Selector;
  import java.nio.channels.ServerSocketChannel;
  import java.nio.channels.SocketChannel;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Set;
  import java.util.Timer;
  import java.util.TimerTask;
  
  public class NioServer {
  
      /**
       * @param args
       */
      private int port = 20001;
      final makeFlagFalse timerFlag = new makeFlagFalse();
      static makeFlagFalse loginLoopBoolean = new makeFlagFalse();
      private static ByteBuffer sBuffer = ByteBuffer.allocate(1024);
      private static ByteBuffer rBuffer = ByteBuffer.allocate(1024);
      private static Map&lt;SocketChannel, Integer&gt; clientsMap = new HashMap&lt;SocketChannel, Integer&gt;();
      private Selector selector = null;
      private ServerSocketChannel serverSocketChannel = null;
      private Object gate = new Object();
  
      public NioServer(int port) {
          this.port = port;
          try {
              init();
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      public static void main(String[] args) throws InterruptedException, IOException {
          final NioServer server = new NioServer(20001);
          Thread accept = new Thread() {
              public void run() {
                  server.accept();
              }
          };
  
          accept.start();
          while (loginLoopBoolean.flag == true) 
              server.loginService();
          server.gamePlay(clientsMap);
      }
  
      public void init() throws IOException {
          selector = Selector.open();
          serverSocketChannel = ServerSocketChannel.open();
          serverSocketChannel.socket().setReuseAddress(true);
          // serverSocketChannel.configureBlocking(false);
          serverSocketChannel.socket().bind(new InetSocketAddress(port));
          System.out.println("服务器启动");
      }
  
      public void accept() {
          while (true) {
              try {
                  SocketChannel socketChannel = serverSocketChannel.accept();
                  System.out.println("receive the connection from "
                          + socketChannel.socket().getInetAddress() + ":"
                          + socketChannel.socket().getPort());
  
                  socketChannel.configureBlocking(false);
                  synchronized (gate) {
                      selector.wakeup();
                      socketChannel.register(selector, SelectionKey.OP_READ);
                  }
              } catch (Exception e) {
                  e.printStackTrace();
                  System.out.println(e.getMessage());
                  System.out.println("Damn it");
              }
          }
      }
  
      public void loginService() throws InterruptedException {
  
  
              synchronized (gate) {
              }
              try {
                  int n = selector.select();
                  if (n == 0){}
                  else{
                  Set&lt;SelectionKey&gt; selectionKeys = selector.selectedKeys();
                  for (SelectionKey key : selectionKeys) {
                      try {
                          if (key.isReadable()) {
                              handle_receive_login(key);
                          }
                      } catch (Exception e) {
                          try {
                              if (key != null) {
                                  key.cancel();
                                  key.channel().close();
                              }
                          } catch (Exception ex) {
                              e.printStackTrace();
                          }
                      }
                  }
                  selectionKeys.clear();
                }
              } catch (Exception e) {
                  e.printStackTrace();
              }
  
      }
  
      public void handle_receive_login(SelectionKey key) {
          SocketChannel socketChannel = null;
          ServerMessage message = null;
          ServerMessage sendMessage = new ServerMessage();
          socketChannel = (SocketChannel) key.channel();
          rBuffer.clear();
          try {
              int count = socketChannel.read(rBuffer);
              if (count &gt; 0) {
                  rBuffer.flip();
                  message = ServerMessage.byte2Message(rBuffer.array());
                  System.out.println("Receive from"+ socketChannel.socket().getInetAddress() + " : "+ message.getb());
                  switch(message.getb()){
                  case(1):
                          int valid = DB.idCheck(message.getUsername(),
                                  message.getPassword());
                          sendMessage.setb((byte) 2);
                          sendMessage.setValid(valid);
                          sendMes sendMes = new sendMes(sendMessage, socketChannel);
                          sendMes.send();
  
                      break;
                  case(2):
                      break;
                  case (3):
                      if(timerFlag.flag){
                          if(message.getReady() == 1){
                              if(clientsMap.size() &lt; 6){
                                  clientsMap.put(socketChannel, clientsMap.size() + 1);
                                  sendMessage.setb((byte) 3);
                                  sendMessage.setReady(1);
                                  sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
                                  sendMes1.send();
                              }
  
                              else{
                                  sendMessage.setb((byte) 3);
                                  sendMessage.setReady(0);
                                  sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
                                  sendMes1.send();
                              }
  
                              Timer timer = new Timer();
  
                              System.out.println("flag is " + timerFlag.flag);
                              TimerTask task = new TimerTask(){
                                  public void run(){
                                      timerFlag.falsify();
                                      System.out.println("flag now is " + timerFlag.flag);
                                  }
                              };
                              timer.schedule(task, 20*1000);
                          }
                      }else{
                          sendMessage.setb((byte) -1); /*-1 implies that game is currently in progress*/
                          sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
                          sendMes1.send();
                      }
                      break;
  
                  case (4):
                      if(timerFlag.flag == true){
                          sendMessage.setb((byte) -2); /*send message saying "waiting for other players*/
                          sendMes sendMes1 = new sendMes(sendMessage, socketChannel);
                          sendMes1.send();
                      }else{
                          loginLoopBoolean.falsify();
                      }
                      break;
                  }   
              }/*end of if(count=0)*/
          } catch (Exception e) {
              e.printStackTrace();
              key.cancel();
              try {
                  socketChannel.close();
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          }
  
      }
  
  
      public void gamePlay(Map&lt;SocketChannel, Integer&gt; clientsMap) throws IOException, InterruptedException{
          Dealer dealer = new Dealer();
          dealer.createDeck();
          ServerMessage sendMessage = new ServerMessage();
  
          if(!clientsMap.isEmpty()){  
              Set&lt;SocketChannel&gt; clientSet = clientsMap.keySet();
              Iterator&lt;SocketChannel&gt; iterator=clientSet.iterator();
              SocketChannel currentPlayer;
              while(iterator.hasNext()){
                  currentPlayer=iterator.next();  
                  sendMessage.setb((byte) 4);
                  sendMessage.setCard1(dealer.dealCard(dealer.deck));
                  sendMessage.setCard2(dealer.dealCard(dealer.deck));
                  sendMes sendMes1 = new sendMes(sendMessage, currentPlayer);
                  sendMes1.send();
              }
              //send who's turn it is 
              loginService();
          }
      }
  
      public static class makeFlagFalse{
          boolean flag;
          public makeFlagFalse() {
              this.flag = true;
          }
          public void falsify(){
              flag = false;
          }
          public void makeTrue(){
              flag = true;
          }
      }
  
      public class sendMes{
          ServerMessage message;
          SocketChannel currentPlayer;
  
          sendMes(ServerMessage message,SocketChannel currentPlayer){
              this.message = message;
              this.currentPlayer=currentPlayer;
          }
          public void send() throws IOException{
              sBuffer.clear();
              sBuffer.put(message.Message2Byte());
              sBuffer.flip();
              currentPlayer.write(sBuffer);
          }
      }
  
  
  }
  </code></pre>
  
  <p>I'm appreciative of any kind of help.  </p>
  
  <p>Thank you</p>