2

I am trying to poll a socket on server side to check if client is still available. I checked a few threads here but nothing seems to work.

As I found out there is no direct way of checking that so I tried to perform write opperation to socket and... Java is writing to the socket (when the client is disconnected) and I get no exception where IOException is expected.

I set a thread that is supposed to perform polling sending packet each second. While sending to disconnected client after about a minute I get response that "operation timed out".

I also tried to mess around with socket setSoTimeout but it doens't work as expected either.

Anyone has any suggestions how to make it work?

Thank you very much in advance.

Best regards, Tom

Tomasz Łoś
  • 79
  • 2
  • 10
  • On the client machine, is there a virus-scanner running? I encountered the case when I checked reachability by trying to connect and the virus-scanner caused all connections to be set up correctly, but they were "fake". Just to be sure: We're talking about TCP, right? – Fildor Sep 03 '13 at 18:42
  • Yes, we are talking about TCP. Virus-scanner is not an issue, as client is iOS device, and I'm literally disconnecting the device by disabling network. So no way it will keep working. – Tomasz Łoś Sep 03 '13 at 19:40

2 Answers2

2

Ok guys, I finally found the solution that actually works:

InetAddress addr = InetAddress.getByName("192.168.1.121");
addr.isReachable(1000)

Works like a charm and reacts very fast. In fact I use it together with socket so in my case it works like this:

new Thread() {
  public void run() {
     while(true) {

        try{
            ArrayList<Socket> arr = new ArrayList(clients.values());
                for(int i=0; i<Main.clients.size(); i++){
                    try
                     {
                        InetAddress addr = InetAddress.getByName(arr.get(i).getInetAddress().toString().replace("/", ""));

                        System.out.println(addr.isReachable(1000));


                     }
                     catch (IOException e)
                     {
                    System.out.println("connection probably lost");
                                    e.printStackTrace();
                      }
                 }
          Thread.sleep(1000);
         } catch (Exception e) { System.out.println("Shit happens: "+e); }
      }}
}.start();

It's not really optimized code and it looks bad, but you get the ideas behind it. The whole code is for reachable hosts detection thread.

Santhosh
  • 335
  • 1
  • 4
  • 23
Tomasz Łoś
  • 79
  • 2
  • 10
1

WHy not do a receive call and then catch exceptions. If you get a broken pipe exception or socket timeout, then you know that the client is no longer present.

For such cases, the typical approach is for the server to set TCP keepalive using the setKeepAlive and getKeepAlive methods. http://docs.oracle.com/javase/6/docs/api/java/net/Socket.html . If the client goes away, then TCP keepalive would kick in (becuase of inactivity) and it would detect that the client is disconnected. Then, it will close the connection. Any subsequent recv() call would return with a value of -1 and error indicating the same.

Manoj Pandey
  • 4,528
  • 1
  • 17
  • 18
  • Thank you very much for your answer, tho KeepAlive is pointless as the interval of sending ping packets due to some information I found on the net is about 2 hours (platform dependent). I need reaction in about 1-5 seconds. – Tomasz Łoś Sep 03 '13 at 19:42
  • 1
    I agree. I wish Java's setKeepAlive method provided an option to tweak these values. However, you can always tweak the global values for the OS. For example, in Linux, one can set these params to even smaller values. Here: http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/ If you are using non-LInux, you might have to do some similar research. But, these settings would affect all connections, something to keep in mind. – Manoj Pandey Sep 03 '13 at 20:02
  • Thank you, but that's a problem - my server is running much more services and some of them may not like messing arround with those parameters – Tomasz Łoś Sep 04 '13 at 09:03