CausingUnderflowsEverywhere CausingUnderflowsEverywhere -4 years ago 235
Java Question

Apache Mina, How to detect when you're sending messages using an invalid socket to the client side?

I have a server setup using MINA version 2.
I don't have much experience with sockets and tcp.

The problem is if I make a connection to my server, and then unplug my internet and close the connection, (Server doesn't get notification of the connection being closed) the server will forever think that my connection is still active and valid.

The server will continue to send messages to my connection, and doesn't throw any exceptions even though there is nothing on my computer binded to the local port.

How can I test that the connection still exists?

I've tried running MINA logging in debug mode, and logging the

IoSession.isConnected() IoSession.isActive IoSession.isClosing


They always return true, true, false. Also, in debug mode, there was no useful information stating that the connection was lost. It just logged the regular "sent message" stuff, as if there was nothing wrong.

From using Flash actionscript, I have had experiences where flash will throw errors that it's operating on an invalid socket. That leads me to believe that it's saying the socket on the server is no longer valid for the connection. So in other words if flash can detect invalid sockets, a Java server should be able to detect it too correct?

If there is truly no way to detect dead connections, I can always setup a connection keep alive routine where the client is constantly sending an "I'm here" message to the server, and the server closes sessions that havent had an incoming message for a period of seconds.




EDIT: After learning that "sockets" are private and never shared over the network I managed to find better results for my issue and I found this SO thread.



Java socket API: How to tell if a connection has been closed?

Unfortunately


IOException 'Connection reset by peer' Doesn't occur when I write to
the IoSession in MINA.





Edit:



Is there any way at all in Java to detect when an ACK to a TCP packet was not received after sending a packet? An ACK Timeout?




Edit:



Yet apparantly, my computer should send a RST to the server? According to this answer. http://stackoverflow.com/a/1434592/4425643
But that seems like a bad way of port scanning. Is this how port scanning works? Port scanners send data to a port and the victim's service responds with a RST? Sorry I think I need a new question for all this. But it's odd that MINA doesn't throw connection reset by peer when it sends data. So then my computer doesn't send a RST.

Answer Source

The TCP framework is not exposed to Java. And Java does not provide a means to edit TCP configuration that exists on the OS level.

This means we cannot use TCP keep alive in Java efficiently because we can't change its default configuration values. Furthermore we can't set the timeout for not receiving an ACK for a message sent. (Learn about TCP to discover that every message sent will wait for an ACK (acknowledgement) from the peer that the message has been successfully delivered.)

Java can only throw exceptions for cases such as a timeout for not completing the TCP handshake in a custom amount of time, a 'Connection Reset by Peer' exception when a RST is received from the peer, and an exception for an ACK timeout after whatever period of time that may be.

To dependably track connection status, you must implement your own Ping/Pong, Keep Alive, or Heartbeat system as @Dog suggested in his answer. (The server must poll the client to see if it's still there, or the client has to continuosly let the server know it's still there.)

For example, configure your client to send a small packet every 10 seconds. In MINA, you can set a session reader idle timeout, which will send an event when a session reader has been idle for a period of time. You can terminate that connection on delivery of this event. Setting the reader timeout to be a bit longer than the small packet interval will account for random high latency between the client and server. For example, a reader idle timeout of 15 seconds would be lenient in this case.

If your server will rarely experience session idling, and you think you can save bandwidth by polling the client when the session has gone idle, look into using the Apache MINA Keep Alive Filter.

https://mina.apache.org/mina-project/apidocs/org/apache/mina/filter/keepalive/KeepAliveFilter.html

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download