Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

BufferedReader.readLine() blocking. 2

Status
Not open for further replies.

Durkin

Programmer
Nov 6, 2000
304
GB
Hi. I'm using a bufferreader with the readline routine to read data from a socket. My problem is that when I get to the last line to be read it hangs as if it is waiting for the line to come through. The documentation seems to suggest that a null should be returned when the end of the stream is reached but this does not seem to be the case. Also, using Bufferreader.ready() doesn't work either.
Here is the main loop of the code:
Code:
String s;
BufferedReader in;
in = new BufferedReader(new  InputStreamReader(skt.getInputStream()));

while (s != null){
    s = in.readLine();
}
Thanks in advance for your help. Durkin
 
That will work if the sender closes the socket, but, that's not how it works when you are keeping the connection open.

To maintain an open connection you need a protocol so you know when you received the end of the message.

Hope this helps
-pete
 
Generally you can put the socket reader code in a separate thread, that way it can block forever on the read quiet happily until more data arrives, in which case it can accept the data and pass it on to some other thread before looping back to the readline() where it will block again.

That being said, it is not really what you where asking, i don't think.

You say "My problem is that when I get to the last line to be read it hangs as if it is waiting for the line to come through" which reads as though the program reads everyline EXCEPT the last line. Is this correct? Or am I misreading it (totally possible).
-------------------------------------------
There are no onions, only magic
-------------------------------------------
 
palbano, the problem was actually as jfryer said - the last line was not coming through. The problem I found was that the last line did not have a line terminator on the end so I added one and it came through. However, the connection would still block waiting for more data so I had to do like you suggested and check each line as it came in for what is expected at the end of the stream. jfryer, I have got each processing of the requests in their own stream which means they don't block the whole app.
However this said, if the service providing the data has something wrong with it and isn't going passing back the correct end of transmission line then the threads are going to build up and up. My problem now is, is there a way to timeout a readLine() call after a certain period? Maybe before each call I should spawn another thread to monitor the readline() and make sure it doesn't hang but this sounds a bit messy. Any ideas?
BTW, thanks for your replies.[thumbsup2] Durkin
 
Have a look in the Java documentation API at the java.net.Socket entry (if you havent already done so [smiley]).

There are a pile of boolean options that can be set to configure the socket to your hearts content.

I admit I'm not to great on the technical side of sockets, I know the code, Im just not too hot on how sockets themselves work so you may find more meaning in those options then I do.

A code solution would be to do as you say, where each socket reader implements an internal thread that checks to see if any action has occured after a certain time period, and if not it issues a shut down command for that reader.
Its not particularily messing, in short
* Create a class that handles the socket communication (which implements Runnable so it is a thread)
* inside that class create new thread (which can bea separate object, or an internal class) which polls for activity inside the first thread (which can be checked for with a boolean flag, set it to true when data has come in and false when you have finished processing the data, if it stays false for too long, kill it)

While swapping between threads is expensive, it should do what you want, particularily if you dont get to mauch data via your sockets at once.


good luck, and let us know what solution you come up with, it would be interesting to know. -------------------------------------------
There are no onions, only magic
-------------------------------------------
 
Doh! There's a method called setSoTimeout on the socket class which works a treat. Durkin
 
Durkin, that does not sound like what you want. that time out is for connecting the TCP/IP stack knows nothing about how you want to use the connection after it is established.

perhaps this might help you

import java.util.Timer;
import java.util.TimerTask;
import java.net.Socket;

/**
* A TimerTask that handles socket connections so that you can time-out
* a socket connection.
*/
public class SocketTask extends java.util.TimerTask {

public static final String VERSION = "1.0";

protected java.net.Socket _sock;

/** Creates new SocketTask */
public SocketTask(java.util.Timer timer, long timeout,
java.net.Socket sock) {

_sock = sock;
timer.schedule( this, timeout);
}

public void run() {
try{

java.util.logging.Logger.global.info("closing socket");
_sock.close();

}catch(Exception ex){

java.util.logging.Logger.global.warning( ex.getMessage());
}
}
}

-pete
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top