4

I've read several questions about this on stack overflow already, but none of them has provided me with an elegant solution.

I know that calling isConnected() and isClosed() on the Socket is useless because it returns the local connection state (if the server is connected - not if the client is connected, as I want).

I also can't simply call if(socket.getInputStream().read()==-1)* because that would only account for the end of the stream (EOS) being reached - i.e., the client didn't send a message recently. This doesn't at all indicate that the client has disconnected however.

I'm considering just having the client send a message to the server letting it know it's disconnecting just before it closes the socket, but I'm wondering if there's a simpler solution I'm missing - wanting to know the connection state of the remote socket is a fairly commonplace desire. Thanks.

*not to mention the fact that InputStream#read() is an abstract method, I'm using DataInputStream for data read methods (i.e. readInt(), readByte(), etc.)

Community
  • 1
  • 1
asaini007
  • 858
  • 5
  • 19
  • You are completely mistaken about what EOS means. It means the peer has disconnected or shutdown the connection. DataInputStream objects do not 'eschew' anything. You're making it up. It provides more methods, period. And the extra methods throw EOFException. You may as well use it. You have to detect it anyway. – user207421 Dec 13 '13 at 05:38
  • So "end of stream" doesn't mean reaching the "end" of the stream (because a stream is continuous and doesn't have a start or an end), but that the stream has "ended"?I forgot that by extending FilterInputStream, DataInputStream inherits it's read() method. And as for EOFException: "if this stream reaches the end before reading all the bytes." Is "reaching the end" the connection being disconnected? Thanks – asaini007 Dec 13 '13 at 06:01
  • Nonsense. End of stream is end of stream. A file stream starts at the beginning of the file and ends at the end of the file. A TCP stream starts when the connection is created and ends when the peer closes the connection or shuts it down. And when that happens, Java `read()` returns -1, `readLine()` returns null, and all other `readXXX()` methods throw `EOFException.` – user207421 Dec 13 '13 at 06:09
  • Ok, that's what I wasn't getting. Thanks – asaini007 Dec 13 '13 at 06:12

1 Answers1

1

I'm considering just having the client send a message to the server letting it know it's closing just before it closes the socket,

Why? It's pointless. You will read this message instead of getting -1 from read(). The latter is all you need. The extra read() in your post is certainly a bad idea, but the read that reads messages isn't. You need that, and you will get EOS from it. You don't need an extra message to tell you the same thing.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • On second though, EOS doesn't mean that the socket is closed though, just that the client hasn't sent any messages to the stream recently (gonna edit that out of my question since it doesn't at all work I think) – asaini007 Dec 13 '13 at 04:31
  • The message the client would send would be read by the server normally, but it would have a specific syntax to indicate that it means "socket is closing". Each time the server receives a message it'd check if that message is "special" (if it has that syntax). That's the only solution I can think of. – asaini007 Dec 13 '13 at 04:42
  • @asaini007 That is not correct. EOS means the peer has closed the connection, or at least shut it down for output. It has nothing whatsoever to do with "hasn't sent any messages to the stream recently". If you're reading messages you're in a position to detects EOS and react to it. An extra message adds nothing whatsoever. – user207421 Dec 13 '13 at 05:36
  • Thanks, this answers my question. I didn't realize EOS was what I needed all along. – asaini007 Dec 13 '13 at 06:13
  • Now that I'm trying to use the read() method as you suggested, I recall the original reason I didn't use it - it blocks until data in available. I've been using `FilteredInputStream#available()>0` to circumvent that issue - but I don't think it can detect EOS. – asaini007 Dec 13 '13 at 16:53