This question already has answers here:
How to detect a remote side socket close? [duplicate]
(4 answers)
Closed 9 years ago.
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.)
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.
Related
This question already has an answer here:
How can I set Socket write timout in java?
(1 answer)
Closed 5 years ago.
In java, Socket has a method setSoTimeout that can be used to specify the reading timeout, but there is no method to specify the writing timeout
When I searched google, a lot of responses like "use nio and selectors", it looks that SocketChannel provides the way to specify the writing timeout, I brief the code of this class, but I still didn't find out how to do it.
Could someone show some code or some guide? Thanks
One possible way to mitigate the lack of a timeout option on a write call is to simply just set the SO_SNDBUF size via Socket.setSendBuffer to something very high. This will allow subsequent calls for writing to avoid blocking unless the pipe to the remote side gets backed up. If possible, structure your protocol such that you wait for some sort of response to data already sent before sending more data. That way, you won't ever exceed the send buffer.
YMMV.
This question already has answers here:
TCP keep-alive to determine if client disconnected in netty
(4 answers)
Closed 6 years ago.
I'm using Java and Netty to connect to a Unity-Client through a TCP/IP connection.
Sometimes the connection can break and the Unity-guy proposed to send a ping (just a one byte message) every 5 seconds and if the time of reception of the last ping is higher than 30 seconds, the connection is lost.
Do I really need to mesure the time? Isn't it enough to trigger an exception if I try to send something through the socket? Is there a case where a write won't detect a connection loss?
I tagged it Netty since I am using it, but it probably is the same with a simple Socket connection.
I think the real answer is: you have to define for yourself how you want your application to behave.
What I mean is: there are many different problems that could occur to your connection. Writing data, and failing immediately when that doesn't work is just one option to handle that.
You can also envision continuous pinging; for example to detect when the other is just "temporarily" unavailable. In other words: you establish some sort of "heartbeat" monitoring; and thus you enable your application for a "wider range" of potential "reactions".
This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 1 year ago.
I have a Java application that connects to a service using a socket. I always expect to receive something from that socket, and if it disconnects I need to reconnect. Reconnect works fine when I close/open socket from remote application side in normal way. But when the remote application is killed, my Java application does not detect that. I run the thread with:
if (socket.isConnected()) { /* code */ }
This function does not detect when the socket is killed. Why? How to detect that remote socket is killed?
Note: I must use java 1.4
UPD
I do reading from socket input stream acording loggic:
if (in.available()) {...}
This not detects socket is disconnected. Should I use in.read() even if no data available to detect closed socket?
The various isXXX() methods of Socket don't track the actual state, but what has been done to the socket. For example isConnected() will return true even after a socket has been closed, if it has been connected at some point.
The only way to detect if a Socket is still valid is to try to use it, i.e. read or write to it. If an exception is thrown, you need to clean up and reconnect.
This function does not detect when the socket is killed. Why?
These functions only tell you the current state of the Socket object: they don't actively test the line. isConnected() means 'have I ever connected?'.
How to detect that remote socket is killed?
You need to read a message from the connection with an appropriate timeout. If the connection is closed or lost you eventually get an IOException, or a timeout will be reached.
BTW To save error messages, I suggest you send a message indicating a graceful disconnect before closing. This way graceful disconnects can be treated differently to connection failures in term of logging.
This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 7 years ago.
From (Java Network Programming fourth edition):
To tell if a socket is currently open, you need to
check that isConnected() returns true and isClosed() returns false. For an example:
boolean connected = socket.isConnected() && ! socket.isClosed();
I need to find a way to discover as soon as possible that the client has disconnected from the Server Socket. Using the trick described above,I have tried the following :
Socket socket = ...;
while (socket.isConnected() && !socket.isClosed()) {
// do something ...
// here, the client is always connected
}
// client is disconnected
The above approach works for me, but it is always correct?. it detects all the cases?
Depending on the application, catching exceptions intelligently would seem like a good solution. The requirement, however, is that you actually wants to send/do something to the client. Possibly a combination of the two approaches suits your specific application. You could try seeing:
Java detect lost connection
The book is wrong, if that's what it really says. isConnected() has nothing to do with whether a socket is currently open. It tells you whether it has ever been connected, which is not at all the same thing.
isOpen() does tell you whether the socket is open, but that doesn't tell you anything about the state of the connection. The test for whether the connection is still open is whether:
read() has returned -1
readLine() has returned null
readXXX() has thrown EOFException for any other X
... all of which indicate that the peer has closed the connection, or
any read or write method has thrown an IOException with the text 'connection reset'.
I recently noticed in my multi threaded Java socket handler that I was getting exceptions when I tried to write on a socket, however I was still receiving data via reads. It was my understanding that if the socket was closed the input stream reader would also throw a socket closed exception when attempting the next read. Is this not the case and should I manually close the socket if I get this exception when attempting to write?
A TCP connection can be closed in the write direction but not in the read direction, such a connection is called "half closed". You should keep reading the rest of the data the other side sent, otherwise the connection will not close normally.
If you think about it, how else could you sanely shut down a TCP connection? If you shut it all the way down in one step, what happens if the other side sends some data to you before you finish shutting it down? You still need to receive it. But, obviously, you can't keep sending data.