title: Java DataInputStream sometimes returns empty
body: <p>I currently am making a messaging application which I will also add encryption to later.
  I have a server which opens a socket and waits for clients to connect. Once client connects, it creates a new thread for that client. and then waits for messages etc.</p>
  
  <p>The problem I am having is that when I try to send the public key exponent and modulus to the client, the Client is unable to use <code>datainputstream(clientSocket.getInputStream()).readLine</code>.</p>
  
  <p>The sending of the exponent and Modulus happen on <code>line 173 and 174</code>.The receiving on the client side happens on line <code>125 and 136</code>.</p>
  
  <p>Server sending the data.
  <code>
      os.println(modulusMap.get(requestName));
      os.println(exponentMap.get(requestName));</code></p>
  
  <p>Client attempting to write the data to a variable:
  <code>
      pubModulusString = is.readLine().trim();<br>
      BigInteger pubModulus = new BigInteger(pubModulusString);<br>
      HashMap&lt;String, BigInteger&gt; modulusMap = new HashMap&lt;String, BigInteger&gt;();
      modulusMap.put(message.substring(1), pubModulus);<br>
      String pubExponentString = is.readLine();</code></p>
  
  <p>I have tested the sending of data as just a print stream and it is working perfectly. It is only when I try to read the data and save it into a variable that the problem occurs<code>(line 125 and 136)</code>.</p>
  
  <p>Majority of the time the <code>readLine()</code> reads the modulus as just blank, but sometimes it will successfully read it. I cannot find a pattern to when it is successful and when it is not.</p>
  
  <p>What is also very weird is that I use the exact same code to send data from client to server. This can be seen on Client side <code>line 89 and 91</code>. And the server receives the data on <code>lines 113 and 119</code>.</p>
  
  <p>Thank you for any help or ideas in advance.</p>
  
  <p>Posted below is the full code for any 1 that is kind enough and has the time to run it.</p>
  
  <p>Server:</p>
  
  <pre><code>    import java.io.*;
  import java.math.*;
  import java.net.Socket;
  import java.net.ServerSocket;
  import java.util.*;
  
  
  
  /*
   * A chat server that delivers public and private messages.
   */
  public class MultiThreadChatServerSync {
  
    // The server socket.
    private static ServerSocket serverSocket = null;
    // The client socket.
    private static Socket clientSocket = null;
  
    // This chat server can accept up to maxClientsCount clients' connections.
    private static final int maxClientsCount = 10;
    private static final clientThread[] threads = new clientThread[maxClientsCount];
  
    public static void main(String args[]) {
  
      // The default port number.
      int portNumber = 2222;
      if (args.length &lt; 1) {
        System.out.println("Usage: java MultiThreadChatServerSync &lt;portNumber&gt;\n"
            + "Now using port number=" + portNumber);
      } else {
        portNumber = Integer.valueOf(args[0]).intValue();
      }
  
      /*
       * Open a server socket on the portNumber (default 2222). Note that we can
       * not choose a port less than 1023 if we are not privileged users (root).
       */
      try {
        serverSocket = new ServerSocket(portNumber);
      } catch (IOException e) {
        System.out.println(e);
      }
  
      /*
       * Create a client socket for each connection and pass it to a new client
       * thread.
       */
      while (true) {
        try {
          clientSocket = serverSocket.accept();
          int i = 0;
          for (i = 0; i &lt; maxClientsCount; i++) {
            if (threads[i] == null) {
              (threads[i] = new clientThread(clientSocket, threads)).start();
              break;
            }
          }
          if (i == maxClientsCount) {
            PrintStream os = new PrintStream(clientSocket.getOutputStream());
            os.println("Server too busy. Try later.");
            os.close();
            clientSocket.close();
          }
        } catch (IOException e) {
          System.out.println(e);
        }
      }
    }
  }
  
  /*
   * The chat client thread. This client thread opens the input and the output
   * streams for a particular client, ask the client's name, informs all the
   * clients connected to the server about the fact that a new client has joined
   * the chat room, and as long as it receive data, echos that data back to all
   * other clients. The thread broadcast the incoming messages to all clients and
   * routes the private message to the particular client. When a client leaves the
   * chat room this thread informs also all the clients about that and terminates.
   */
  class clientThread extends Thread {
  
    private String clientName = null;
    private DataInputStream is = null;
    private BufferedReader inputLine = null;
    private PrintStream os = null;
    private Socket clientSocket = null;
    private final clientThread[] threads;
    private int maxClientsCount;
  
    public clientThread(Socket clientSocket, clientThread[] threads) {
      this.clientSocket = clientSocket;
      this.threads = threads;
      maxClientsCount = threads.length;
    }
  
    public void run() {
      int maxClientsCount = this.maxClientsCount;
      clientThread[] threads = this.threads;
      HashMap&lt;String, BigInteger&gt; modulusMap = new HashMap&lt;String, BigInteger&gt;();
      HashMap&lt;String, BigInteger&gt; exponentMap = new HashMap&lt;String, BigInteger&gt;();
      try {
        /*
         * Create input and output streams for this client.
         */
        is = new DataInputStream(clientSocket.getInputStream());
        os = new PrintStream(clientSocket.getOutputStream());
        inputLine = new BufferedReader (new InputStreamReader(System.in));
        String name;
        while (true) {
          os.println("Enter your name.");
          name = is.readLine().trim();
  
          String pubModulusString = is.readLine().trim();
          BigInteger pubModulus = new BigInteger(pubModulusString);
  
  
          modulusMap.put(name, pubModulus);
  
          String pubExponentString = is.readLine().trim();
          BigInteger pubExponent = new BigInteger(pubExponentString);
  
  
          exponentMap.put(name, pubExponent);
  
  
          if (name.indexOf('@') == -1) {
            break;
          } else {
            os.println("The name should not contain '@' character.");
          }
        }
  
        /* Welcome the new the client. */
        os.println("Welcome " + name
            + " to our chat room.\nTo leave enter /quit in a new line.");
        synchronized (this) {
          for (int i = 0; i &lt; maxClientsCount; i++) {
            if (threads[i] != null &amp;&amp; threads[i] == this) {
              clientName = "@" + name;
              break;
            }
          }
          for (int i = 0; i &lt; maxClientsCount; i++) {
            if (threads[i] != null &amp;&amp; threads[i] != this) {
              threads[i].os.println("*** A new user " + name
                  + " entered the chat room !!! ***");
            }
          }
  
  
  
  
  
  
  
  
          }
        /* Start the conversation. */
        while (true) {
          String line = is.readLine();
          if (line.startsWith("/quit")) {
            break;
          }
  
  
          if (line.startsWith("!")){
  
  
          String requestName;
              requestName = line;
              requestName = requestName.substring(1);
  
              os.println(modulusMap.get(requestName));
              os.println(exponentMap.get(requestName));
  
          }
          else {
  
  
  
          /* If the message is private sent it to the given client. */
          if (line.startsWith("@")) {
            String[] words = line.split("\\s", 2);
            if (words.length &gt; 1 &amp;&amp; words[1] != null) {
              words[1] = words[1].trim();
              if (!words[1].isEmpty()) {
                synchronized (this) {
                  for (int i = 0; i &lt; maxClientsCount; i++) {
                    if (threads[i] != null &amp;&amp; threads[i] != this
                        &amp;&amp; threads[i].clientName != null
                        &amp;&amp; threads[i].clientName.equals(words[0])) {
                      threads[i].os.println("&lt;" + name + "&gt; " + words[1]);
                      /*
                       * Echo this message to let the client know the private
                       * message was sent.
                       */
                      this.os.println("&gt;" + name + "&gt; " + words[1]);
                      break;
                    }
                  }
                }
              }
            }
          } else {
            /* The message is public, broadcast it to all other clients. */
            synchronized (this) {
                this.os.println("Please select who you wish to message by typing '@username *Your Message*'");
            }
          }
          }
        }
        synchronized (this) {
          for (int i = 0; i &lt; maxClientsCount; i++) {
            if (threads[i] != null &amp;&amp; threads[i] != this
                &amp;&amp; threads[i].clientName != null) {
              threads[i].os.println("*** The user " + name
                  + " is leaving the chat room !!! ***");
            }
          }
        }
        os.println("*** Bye " + name + " ***");
  
        /*
         * Clean up. Set the current thread variable to null so that a new client
         * could be accepted by the server.
         */
        synchronized (this) {
          for (int i = 0; i &lt; maxClientsCount; i++) {
            if (threads[i] == this) {
              threads[i] = null;
            }
          }
        }
        /*
         * Close the output stream, close the input stream, close the socket.
         */
        is.close();
        os.close();
        clientSocket.close();
      } catch (IOException e) {
      }
    }
  }
  </code></pre>
  
  <p>Client</p>
  
  <pre><code>    import java.io.DataInputStream;
  import java.io.*;
  import java.math.*;
  import java.math.BigInteger;
  import java.net.Socket;
  import java.net.ServerSocket;
  import java.net.UnknownHostException;
  import java.security.*;
  import java.security.spec.*;
  import java.util.*;
  
  import javax.crypto.*;
  
  
  
  public class MultiThreadChatClient implements Runnable {
  
    // The client socket
    private static Socket clientSocket = null;
    // The output stream
    private static PrintStream os = null;
    // The input stream
    private static DataInputStream is = null;
  
    private static BufferedReader inputLine = null;
    private static boolean closed = false;
  
  
    private static final String PUBLIC_KEY_FILE = "Public.key"; 
    private static final String PRIVATE_KEY_FILE = "Private.key"; 
  
    public static void main(String[] args) {
  
  
  
      // The default port.
      int portNumber = 2222;
      // The default host.
  String host = "192.168.0.16";
  
      if (args.length &lt; 2) {
        System.out
            .println("Usage: java MultiThreadChatClient &lt;host&gt; &lt;portNumber&gt;\n"
                + "Now using host=" + host + ", portNumber=" + portNumber);
      } else {
        host = args[0];
        portNumber = Integer.valueOf(args[1]).intValue();
      }
  
      /*
       * Open a socket on a given host and port. Open input and output streams.
       */
      try {
        clientSocket = new Socket(host, portNumber);
        inputLine = new BufferedReader(new InputStreamReader(System.in));
        os = new PrintStream(clientSocket.getOutputStream());
        is = new DataInputStream(clientSocket.getInputStream());
      } catch (UnknownHostException e) {
        System.err.println("Don't know about host " + host);
      } catch (IOException e) {
        System.err.println("Couldn't get I/O for the connection to the host "
            + host);
      }
  
      /*
       * If everything has been initialized then we want to write some data to the
       * socket we have opened a connection to on the port portNumber.
       */
      if (clientSocket != null &amp;&amp; os != null &amp;&amp; is != null) {
        try {
  
          /* Create a thread to read from the server. */
          new Thread(new MultiThreadChatClient()).start();
  
          String myName = inputLine.readLine();
          os.println(myName.trim());
  
          try { 
             KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 
             keyPairGenerator.initialize(2048); //1024 used for normal securities 
             KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
             PublicKey publicKey = keyPair.getPublic(); 
             PrivateKey privateKey = keyPair.getPrivate(); 
  
             //Pullingout parameters which makes up Key 
             KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
             RSAPublicKeySpec rsaPubKeySpec = (RSAPublicKeySpec) keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class); 
             RSAPrivateKeySpec rsaPrivKeySpec = (RSAPrivateKeySpec) keyFactory.getKeySpec(privateKey, RSAPrivateKeySpec.class); 
             os.println(rsaPubKeySpec.getModulus());
             System.out.println(rsaPubKeySpec.getModulus());
             os.println(rsaPubKeySpec.getPublicExponent()); 
  
             FileOutputStream fos = null; 
             ObjectOutputStream oos = null;
  
             fos = new FileOutputStream(PUBLIC_KEY_FILE); 
             oos = new ObjectOutputStream(new BufferedOutputStream(fos)); 
  
             oos.writeObject(rsaPubKeySpec.getModulus());
             oos.writeObject(rsaPubKeySpec.getPublicExponent());
  
             oos.close();
             fos.close();
  
             fos = new FileOutputStream(PRIVATE_KEY_FILE); 
             oos = new ObjectOutputStream(new BufferedOutputStream(fos)); 
  
             oos.writeObject(rsaPrivKeySpec.getModulus());
             oos.writeObject(rsaPrivKeySpec.getPrivateExponent());
  
             oos.close();
             fos.close();
  
            } catch (NoSuchAlgorithmException e) { 
             e.printStackTrace(); 
            }catch (InvalidKeySpecException e) { 
             e.printStackTrace(); 
            } 
  
          while (!closed) {
          String message = inputLine.readLine();
              if (message.startsWith("!")){
                  os.println(message.trim());
  
                  String pubModulusString = is.readLine().trim();
  
  
                  BigInteger pubModulus = new BigInteger(pubModulusString);
  
                  HashMap&lt;String, BigInteger&gt; modulusMap = new HashMap&lt;String, BigInteger&gt;();
  
                  modulusMap.put(message.substring(1), pubModulus);
  
  
                  String pubExponentString = is.readLine();
                  BigInteger pubExponent = new BigInteger(pubExponentString);
  
                  HashMap&lt;String, BigInteger&gt; exponentMap = new HashMap&lt;String, BigInteger&gt;();
  
                  exponentMap.put(message.substring(1), pubExponent);
  
  
                  System.out.println(modulusMap.get(message.substring(1)) + " Hi");
                  System.out.println(exponentMap.get(message.substring(1)) + "asdk");
  
              }
              else{
                  // INSERT ENCRYPTION ON "message" here
                  os.println(message.trim());
              }
  
  
  
  
          }
          /*
           * Close the output stream, close the input stream, close the socket.
           */
          os.close();
          is.close();
          clientSocket.close();
        } catch (IOException e) {
          System.err.println("IOException:  " + e);
        }
      }
    }
  
    /*
     * Create a thread to read from the server. (non-Javadoc)
     *
     * @see java.lang.Runnable#run()
     */
    public void run() {
      /*
       * Keep on reading from the socket till we receive "Bye" from the
       * server. Once we received that then we want to break.
       */
      String responseLine;
      try {
        while ((responseLine = is.readLine()) != null) {
          System.out.println(responseLine);
          if (responseLine.indexOf("*** Bye") != -1)
            break;
        }
        closed = true;
      } catch (IOException e) {
        System.err.println("IOException:  " + e);
      }
    }
  
  }
  </code></pre>