buffered reader not receiving data from socket

16,794

Solution 1

Firstly you should call BufferedReader.ready() before calling readLine(), as the ready() will tell you if it's ok to read.

PrintWriter doesn't throw I/O Exception so the write may have failed without your knowledge which is why there is nothing to read. Use PrintWriter.checkError() to see if anything as gone wrong during the write.

You ought to set up the input and output streams on the Socket at the same time before you write anything down the pipe. If your reader is not ready when the other end tries to write you will get a broken pipe in the server and it won't send any more data. Telnet sets up read and write before you have written or read anything.

You can make use of Wireshark to tell if the server is actually sending data.

Solution 2

BufferdReader.readLine() reads lines, i.e. sequences of characters ended with \r or \r\n. I guess that your server writes its output into one single line. Your telnet output proves this assumption. Just use PrintWriter.println() at server side.

Share:
16,794
Ryan
Author by

Ryan

Updated on June 11, 2022

Comments

  • Ryan
    Ryan almost 2 years

    I am writing a client application that will receive a continuous flow of data through tcp/ip. The problem I'm having is that the buffered reader object isn't receiving any data and is hanging at the readline method.

    The way the server works is that you connect to it, and then send authentication information in order to receive data. The gist of my code is below

    socket = new Socket(strHost, port);
    authenticate();
    inStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    process(inStream);
    
    authenticate()
    {      
      PrintWriter pwriter = new PrintWriter(socket.getOutputStream(), true);
      pwriter.println(authString);
    }
    
    process(BufferedReader bufferedReader)
    {
       while((line = bufferedReader.readLine()) != null)
          dostuff
    }
    

    I created a sample server application that sends data the way (I think) the server is sending data and it connects, and receives and processes the data fine. I can connect to the server fine in my application. I can also telnet to the server and write the authentication string and receive a flood of data using telnet. However my application just hangs at readLine with the server and I'm out of idea's why.

    The data coming in (through telnet atleast) looks like a continuous stream of the following:

     data;data;data;data;data
     data;data;data;data;data
    

    Why is my app hanging at readline, am I not outputting the authentication line correctly? I'm not receiving any errors...

    EDIT My sample server code (which is working correctly)...again this is only mimicking the way I think the real server is running but I can connect to both in my application just not receive data from the real server.

      public static void main(String[] args) throws IOException
      {
      ServerSocket serverSocket = null;
    
      try
      {
         serverSocket = new ServerSocket(1987);
      }
      catch (IOException e)
      {
         System.out.println("Couldn't listen on port: 1987");
         System.exit(-1);
      }
    
      Socket clientSocket = null;
      try
      {
         clientSocket = serverSocket.accept();
      }
      catch (IOException e) {
         System.out.println("Accept failed: 1987");
         System.exit(-1);
      }
    
      PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
      BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
      String something;
    
      while ((something = in.readLine()) != null)
      {
         while(true)
         {
            out.println(message);
         }
      }
    
    
    
      out.close();
      in.close();
      clientSocket.close();
      serverSocket.close();
    }
    
  • toto2
    toto2 almost 13 years
    Or he'll have to use read(char[] cbuf, int off, int len) if it's a long continuous stream.
  • Ryan
    Ryan almost 13 years
    bufferedreader.ready seemed to do the trick, thanks for the tip on the printwriter.checkerror as well I'm adding that to my code.
  • class stacker
    class stacker over 11 years
    @DavidNewcomb Why should I set up, say, a BufferedReader from a socket's InputStream before I send something? Does it really eat data which arrives beforehand? How does this work with data sources which always have initial data available? -- I'd expect any Stream wrapper to fetch, but not eat initial data?
  • David Newcomb
    David Newcomb over 11 years
    With BufferedXxx you can not say when the reads or writes will actually happen. The communications channel is a pipe and pipes must have readers and writers working together. It doesn't eat data, you get a broken pipe if you try to write something and there is nothing to read it, in the same way as your read will block if no one is writing at the other end.
  • user207421
    user207421 almost 7 years
    BufferedReader.ready() is pointless both here and in most other uses. It doesn't tell you that a complete line has arrived, so readLine() is still liable to block until the line terminator arrives.
  • David Newcomb
    David Newcomb almost 7 years
    @EJP, It worked in this case didn't it! Generally if you are reading lines the thing at the other end is writing lines, so the system balances as carriage returns at the other end force a stream flush. When you call ready() it is highly likely you will get a whole line. From reading the code BufferedReader.readLine() reads any available data in a non-blocking way until the stream ends or a new line is reached. While readLine appears to block it doesn't, it loops internally checking for data and reading it. It's a subtle difference but important when talking about CPU usage.
  • David Newcomb
    David Newcomb almost 7 years
    @EJP, BufferedReader is specifically for "text from a character-input stream" so if you use it on a binary stream you deserve everything you get ;)