Sockets: BufferedReader readLine() blocks
Asked Answered
W

4

11

I am using BufferedReader.readLine() method to read a response from a remote server (which is written in C and I have no access to source code).

BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while((line = br.readLine())!=null){
    [...]
}

But it always blocks at the last line until it times out. So I used the following code:

int b;
while(true){
   b = in.read;
   [...]
}

and I found out that the last byte read has an integer value of 13, which I think it is a carriage return, right?

So why the readLine method blocks? How does the server usually signal an end of stream is reached? Thanks.

Worldshaking answered 26/5, 2011 at 14:2 Comment(2)
Can you please paste your non-blocking code that you use. I am looking to see what can be done for non-blocking inputsDecillion
@PrakharAgrawal What are you talking about? There is no non-blocking code present or mentioned here.Halt
R
11

In the case of a network connection, the stream is terminated when the socket is closed.

So it is perfectly normal that readLine() blocks until it received an "end of line" or you close manually the connection. When your readLine() receives the last character with the '13' value, the line is read and the loop starts again, waiting for the next line.

There is no difference between the "last line" and the other lines.

In order to stop the loop, you must manually close the connection somewhere or wait for the timeout. But without more information about your communication protocol, it is impossible to be more precise about this.

Rhiannonrhianon answered 26/5, 2011 at 14:10 Comment(1)
You're right; the code waits for \r and then remembers to skip the next line feed (if any).Rivers
H
4

It depends on the protocol. If the server doesn't close the stream, readLine will block until the proper line end is received. So if the server never sends the proper line end, you're blocked. You should maybe use more low-level methods and try to get the protocol documentation, or reverse-engineer it.

Haem answered 26/5, 2011 at 14:9 Comment(0)
B
2

make sure that the server code has out.println() instead of out.print()

Biretta answered 23/10, 2013 at 9:22 Comment(0)
B
0

You can extend the while condition if you do not use empty lines :

while((line = br.readLine())!=null && line.length() > 0) {
   // ...
}
Barquisimeto answered 3/1, 2014 at 16:44 Comment(2)
yes, right idea. Another thing you can do is using a special char sequence of the end of message. Declaring something like 'EOM' = \n\n where 'EOM' is EndOfMessageSteadman
Except readLine will block until an end of line is detected or the stream is closed.Tremann

© 2022 - 2024 — McMap. All rights reserved.