0

I've a Socket Program which acts as client. When it initializes connection, Server Sends data periodically and my program acknowledges back.

I've written my program in such a way, when there is an interruption in connection between Client-Server with Socket/network dis-connectivity, Client receives an event in the form of exception and I handle it and used recursions there to keep on looking for the connection to re-establish.

I've tested this with Hercules as a Server.

But when I actually deployed the application, After some certain time I see my program is no longer receiving the data though it is running. And server say Client has not initialized the connection.

So here what I presume is happening is the connection is Idle for long time, Client socket gets disconnected but event not received. Could this happen?

If so, How to handle this? I'm attaching the following example client socket program.

public void connect(String ipAddress, int portNo, int updateValue) {
    Socket socket = null;
    try {
        System.out.println("Connecting ...");
        //socket = new Socket("192.168.3.39",3000);
        socket = new Socket(ipAddress,portNo);
        System.out.println("Timeout: "+socket.getSoTimeout());
        InputStream is = socket.getInputStream();
        byte[] buffer = new byte[512];
        try {
            int read;
            while((read = is.read(buffer)) != -1) {
                System.err.println("The Lengh of the buffer is: "+buffer.length);
                ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream();
                String output = new String(buffer, 0, read);
                System.out.println(output);
                outputBuffer.write(buffer, 0, read);

                //Code snippet to write an integer into PLC
                BufferedOutputStream bw = null;
                try {
                    bw = new BufferedOutputStream(socket.getOutputStream());
                    bw.write(Convert.IntToByteArr(updateValue));  //Here I want to write only integers as bytes.
                    bw.flush();   //Flushing the data
                    System.out.println("Data Flushed");
                } catch (Exception e) {
                    System.err.println("Exception: "+e.getMessage());
                }
            };
            connect(ipAddress, portNo, updateValue);
        } catch(SocketException e) {
            System.err.println("SocketException: "+e.getMessage());
            connect(ipAddress, portNo, updateValue);
        }
        System.out.println("******END*****");//This code will never be executed
    } catch (ConnectException e) {
        System.err.println("Connection Exception: "+e.getMessage());
        connect(ipAddress, portNo, updateValue);
    } catch (Exception e) {
        System.err.println("Generic Exception: "+e.getMessage());
        e.printStackTrace();
        connect(ipAddress, portNo, updateValue);
    }
}
Kishore Kumar Korada
  • 1,204
  • 6
  • 22
  • 47
  • Yes, it's normal that TCP/IP disconnects you if the link is idle for too long. Google for "TCP time out". – markspace Apr 16 '19 at 05:52
  • 1
    Possible duplicate of [Java socket API: How to tell if a connection has been closed?](https://stackoverflow.com/questions/10240694/java-socket-api-how-to-tell-if-a-connection-has-been-closed), [Java detect lost connection](https://stackoverflow.com/questions/969866/java-detect-lost-connection). – Steffen Ullrich Apr 16 '19 at 05:53
  • @markspace When such timeout happens, Client won't receive any events too? If so, it still thinks connection has been established? – Kishore Kumar Korada Apr 16 '19 at 05:56
  • @SteffenUllrich Question what I've asked is pretty much different to what you've marked as possible duplicate. – Kishore Kumar Korada Apr 16 '19 at 05:59
  • @KishoreKumarKorada: *"... what I've asked is pretty much different to what you've marked as possible duplicate"* - I don't think so.The problem is that you expect a SocketException even though there might be none. The questions I've linked to explain how to properly check if there is an actual working connection by transmitting data (i.e. some kind of heartbeat, TCP keep alive would also work). – Steffen Ullrich Apr 16 '19 at 07:01
  • `Client won't receive any events too?` Correct. When a TCP/IP socket times out, the other end is not signaled. Because the link is assumed to be down, no attempt is made to send a disconnect message. You don't find out the link is down until you try to send some data. That's how it works. – markspace Apr 16 '19 at 14:08
  • @markspace Thanks. That makes perfect sense. In the above code snippet what could I do implement heart beat kind of approach? Should I run separate thread with the same socket reference to do it? Or Any good reference could you provide? – Kishore Kumar Korada Apr 17 '19 at 04:44

1 Answers1

0

Yes, when a TCP/IP connection is idle for too long, it will automatically disconnects you.

You could try to figure out if your connection is interrupted by trying to read/write from the socket. If the operation fails, then you have lost your connection. Do this at least before you try to receive/send data, so that your actual actions don't fail. When the test fails, reconnect the socket and continue your action.

Marvin Klar
  • 1,869
  • 3
  • 14
  • 32
  • "You could try to figure out if your connection is interrupted by trying to read/write from the socket". With this, You mean to say, Should I do this outside of the code snippet I've mentioned above? Checking in asynchronous? – Kishore Kumar Korada Apr 16 '19 at 06:42
  • It doesn't really matter where, but somewhere you need to check the connection of your `socket`. In this case you could also put the reading of the data in a try-catch block, where you catch the timeout and then do the reconnect. – Marvin Klar Apr 16 '19 at 06:50