6 Replies Latest reply: Feb 3, 2011 4:37 PM by EJP RSS

    BufferedReader.readLine() hangs

    818943
      Hi.

      I have the following client/server application. This is the server code.
           
      public void run(){                              
      BufferedReader reader=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));                    
                     PrintWriter writer=new PrintWriter(clientSocket.getOutputStream(),true);                    
                     
                     for(int i=0;i<10;i++){
                          reader.readLine();
                     }
                     
      writer.println("OK");
                                                                                                                                   
                     /*Check username*/
                     String username=reader.readLine();                                                                 
                                                   
                     /*Check password*/
                     long t1=System.currentTimeMillis();
                     String receivedPassword=reader.readLine(); //Receive password                                                            
                     System.out.println(System.currentTimeMillis()-t1);
      }                                                  

      When receives password reader.readLine() hangs for 40ms while username is received in less than 1ms.
      I run client and server at the same machine.
      Why it blocks for so long?
        • 1. Re: BufferedReader.readLine() hangs
          EJP
          Show us the client code. If you have a flush() between sending the username and the password, take it out, and flush() after sending the password only.
          • 2. Re: BufferedReader.readLine() hangs
            818943
            client code:

            PrintWriter writer=new PrintWriter(socket.getOutputStream(),true);                               
            BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));                                   


            for (int i=0;i<10;i++) writer.println("setup");
            reader.readLine();
            writer.println(username);                    /*Send username*/     
            sleep(15);
            writer.println(password);                    /*Send password*/
            • 3. Re: BufferedReader.readLine() hangs
              802316
              On linux, the TCP stack tries to combine packet together when it thinks you are about to give a reply. When you don't give a reply, it timeouts at about 40 ms and send the data anyway.
              @ejp can give you a more technical answer, but that is what I have seen.

              If your application was performance sensitive, you wouldn't sleep or send messages you ignore or flush more often than needed.
              This just confuses the OS when it tries to tune for your behaviour.
              • 4. Re: BufferedReader.readLine() hangs
                818943
                I want username and password arrive at server with particular interval.
                That's why i use sleep and flush between username and password.
                I want them to be sent in different packets.
                • 5. Re: BufferedReader.readLine() hangs
                  tschodt
                  815940 wrote:
                  client code:
                  for (int i=0;i<10;++i) {
                  writer.println("setup");
                  }
                  reader.readLine();
                  writer.println(username);                    /*Send username*/     
                  writer.flush();  // << that would be the obvious thing to try to eliminate that 40ms latency that seems to annoy you
                  Thread.sleep(15);
                  writer.println(password);                    /*Send password*/
                  • 6. Re: BufferedReader.readLine() hangs
                    EJP
                    I want them to be sent in different packets.
                    You have no control over that whatsoever, and the sleep() won't help unless you make it well over a second. The TCP/IP stack will do its best to coalesce outgoing packets. If this requirement is due to a security concern you should be using SSL.