简体   繁体   中英

client reconnect java socket

ok i need to write a client that can be able to detect the connection between client and server...once server is close and bring back up my client need to be able to connect it back to the server..but i am really not sure how to do it...any help if possible?

 public TEST(String serverIP, int serverPort){
    Log("Connection to the Server....");
    try{
        socket = new Socket(serverIP, serverPort);
        Log("Connected to the server : "+socket);
        start();
    } catch(UnknownHostException uhe){
        System.out.println("Unknown Host: "+ uhe.getMessage());
    } catch (IOException ioe){
        System.out.println("IO Exception: "+ioe.getMessage());
    }

    String readline = "";

    streamOutput.println("TRY test");

    while(true){
        try{
            readline = streamInput.readLine();
            System.out.println(readline);
        } catch (IOException ioe){
            System.out.println("Error in sending: "+ioe.getMessage());
            return;
        }
    }
}

above is my client code that use to connect to a server once it is compiled...

The only way to know a connection is closed is to try sending data over the wire. Connections don't automatically test open/closed status. If you want to check for an closed connection and reconnect, you'll have to send a heartbeat signal from one to the other. Usually, it's just a special byte or tiny message that tells the other side "I'm still here"

But then, depending on your application, you may not need that. Do both sides of your application start messages? Or is it an RMI-style app? Where the server just listens for requests?

Maybe something like this?

    class Client {
        private Socket socket;
        private boolean tryToReconnect = true;
        private final Thread heartbeatThread;
        private long heartbeatDelayMillis = 5000;

        public Client(final String server, final int port) {
            connect(server, port);
            heartbeatThread = new Thread() {
                public void run() {
                    while (tryToReconnect) {
                        //send a test signal
                        try {
                            socket.getOutputStream().write(666);
                            sleep(heartbeatDelayMillis);
                        } catch (InterruptedException e) {
                            // You may or may not want to stop the thread here
                            // tryToReconnect = false;
                        } catch (IOException e) {
                            logger.warn("Server is offline");
                            connect(server, port);
                        }
                    }
                };
            };
            heartbeatThread.start();
        }

        private void connect(String server, int port){
            try {
                socket = new Socket(server, port);
            } catch (UnknownHostException e) {
                logger.error(e, e);
            } catch (IOException e) {
                logger.error(e, e);
            }
        }

        public void shutdown() {
            tryToReconnect = false;
        }
    }

This is a pretty common problem (needing to know when the pipe is broken) and one of the answers was correct in the approach stating that the Client will need to 'check' the socket (periodically) to see if it is closed. The Server will not notify the Client the socket is closed and indeed, cannot because it is, well, closed. Firewalls, proxies and the like in between the Client and Server may have killed or otherwise blocked socket communication in one or both directions at any point after the connection is made.

First, if you have done a lot of socket programming (in "C" or Java, etc) ... you will have seen the "attempting to write on broken pipe" type error/exception. This is an I/O class of error when the Client tries to write (send) data on a closed socket (which was just then detected to have been closed).

So the answer lies in managing the socket above the Socket creation layer.

That is, a thread on the Client will need to be monitoring the socket by sending data (periodically to the server as a kind of 'ping' to check for a broken-pipe condition) and then destroy (clean-up) and re-create the socket (rinse and repeat) if an I/O error occurs.

Note that a more complex bi-directional bit of logic would be better provided the Client could ensure an expected and consistent (and timely) response from the Server for a given 'ping'. This would concretely confirm the bi-directional traffic is flowing. Otherwise firewalls could be closing traffic in one direction whilst the Client believes it is still 'talking' to the Server (which may well be receiving data but not able to transmit back to the Client - possibly causing it to terminate the connection on inactivity timeout).

It seems you don't need to implement hear beats yourself. They are already implemented in most TCP implementations.

If your connection is TCP, what you are looking for is in a lower layer. Have a look at TCP KeepAlive.


These links might help:

  1. How To Test TCP KeepAlive? .
  2. TCP keepalive overview

When your client catches a SocketException it should enter its tryToReconnect state. Now it probes the server at some interval (eg 1 sec maybe more, depending on the server). Make sure you implement some logic to stop that when it is not needed anymore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM