0

I used the Java Knock Knock tutorial for creating a client-server connection but I cant figure out how to check if the socket is still open.

Simplified code:

try {
    while ((clientMessage = inFromClient.readLine()) != null) {
        //do stuff
    } catch (IOException e) {
        //client disconnected
        e.printStackTrace();
    }
}

This works great, however I noticed that when the client is Linux based the exception isn't thrown if client gets forcefully closed. I tried some suggestions posted by others but can't get any working. I tried to implement a loop that checks how long its been since last message was received but it didn't work, the loop had to be inside the loop in the above code, and the loop is only executed when a new message is received from the client. I'm very confused but I don't understand how to implement any methods of checking.

If I put the method to check for inactivity outside the above loop then it's never called because the socket loop is indefinite (unless socket is closed).

Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
Cody
  • 870
  • 4
  • 21
  • 38
  • possible duplicate of [Java Socket API: How to tell if a connection has been closed?](http://stackoverflow.com/questions/10240694/java-socket-api-how-to-tell-if-a-connection-has-been-closed) – Orel Eraki Apr 19 '14 at 09:01
  • Actually I read that that will still return true even if socket gets closed. BUT the bigger problem is that I CANT call it on a loop. The loop in my code is called only when a message is received, if I add that to the code then it will only be called once (right after a message is received) and thats it. EDIT: It's not a duplicate, please read the question. The problem is not a method detecting IF ITS CLOSED, the problem is getting the method to keep checking more than once. – Cody Apr 19 '14 at 09:01
  • http://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#setSoTimeout%28int%29 – JimmyB Apr 19 '14 at 09:02
  • @Orel Eraki: *wrong*, IMHO `isClosed()` is the right choice as ["Note: Closing a socket doesn't clear its connection state, which means this method will return true for a closed socket (see isClosed()) if it was successfuly connected prior to being closed."](http://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#isConnected%28%29) – try-catch-finally Apr 19 '14 at 09:02
  • 2
    @try-catch-finally, wrong, `isClosed()` will only tell you, if you did the closing and not the other way around. IMHO, he should use the `readLine` or `read` and check the response. – Orel Eraki Apr 19 '14 at 09:04
  • Guys the problem is not checking if its open, the problem is checking it indefinitely. The code for checking has to be in the socket loop, and it will only run ONCE after a message is received from the client. – Cody Apr 19 '14 at 09:06
  • @Cody: I often came across libraries that optimistically read from a socket without checking it's status and chatching `IOException`s instead. Maybe this is OK for you? Further in TCP there might be a state where the other side has closed the connection but not you: I'm not sure if `isClosed()` will return the correct values then. (Please take this into account.) – try-catch-finally Apr 19 '14 at 09:06
  • even if it does, that doesnt help me, how do I run `isClosed()` more than once? If I put the code at the end of the loop it will only be called once and thats after the client sends me a message. If the client doesnt send me a message the `isClosed()` will not be called. – Cody Apr 19 '14 at 09:10
  • @Cody: you might want to start another thread that endlessly loops checking the last time a message was received. Every time you get a message you would reset an inactivity counter or update a last-time-received value. – try-catch-finally Apr 19 '14 at 09:11
  • Does `readLine` return null when the other end of the socket it forcefully closed? – user253751 Apr 19 '14 at 09:12
  • ahh yes thank you immibis. I cant believe I missed such an obvious solution, I guess its late and im tired. Adding code after the while loop is called when the socket is closed from client side. Thanks, if you want you can write an official solution and ill select it as correct. – Cody Apr 19 '14 at 09:45

1 Answers1

3

Just set a read timeout with Socket.setSoTimeout(). Set it to higher than the expected request interval, say double that. If it expires, you will get a SocketTimeoutException: close the socket.

Contrary to some of the comments, isConnected(), isBound(), isClosed(), etc. are no use for this. They tell you whether you connected, bound, closed, etc. the Socket. Not about the state of the connection.

user207421
  • 305,947
  • 44
  • 307
  • 483