клиент переподключить сокет Java - PullRequest
0 голосов
/ 21 марта 2012

хорошо, мне нужно написать клиент, который сможет обнаружить соединение между клиентом и сервером ... как только сервер будет близко и восстановить мой клиент, нужно иметь возможность подключить его обратно к серверу ... но я действительно не знаю, как это сделать ... любая помощь, если это возможно?

 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;
        }
    }
}

выше - мой клиентский код, который используется для подключения к серверу после его компиляции ...

Ответы [ 3 ]

5 голосов
/ 21 марта 2012

Единственный способ узнать, что соединение закрыто, это попытаться отправить данные по проводам. Соединения не проверяют автоматически состояние открытия / закрытия. Если вы хотите проверить наличие закрытого соединения и переподключиться, вам нужно будет отправить сигнал пульса от одного к другому. Обычно это просто специальный байт или крошечное сообщение, которое говорит другой стороне: «Я все еще здесь»

Но тогда, в зависимости от вашего приложения, вам это может не понадобиться. Обе стороны вашего приложения запускают сообщения? Или это приложение в стиле RMI? Где сервер просто слушает запросы?

Может быть, как-то так?

    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;
        }
    }
1 голос
/ 18 апреля 2017

Это довольно распространенная проблема (необходимо знать, когда канал разорван), и один из ответов был правильным в подходе, утверждающем, что Клиент должен будет «проверять» сокет (периодически)чтобы увидеть, если он закрыт. Сервер не будет уведомлять Клиент , что сокет закрыт и, действительно, не может, потому что он, ну, в общем, закрыт.Межсетевые экраны, прокси-серверы и т.п. между Client и Server могли прервать или иным образом заблокировать обмен сокетами в одном или обоих направлениях в любой точке после установления соединения.

Во-первых, если вы много занимались программированием сокетов (на «C» или Java и т. Д.) ... вы увидите ошибку / исключение типа «попытка записи по сломанному каналу».Это класс ошибок ввода / вывода, когда Клиент пытается записать (отправить) данные в закрытый сокет (который был обнаружен закрытым).

Таким образом, ответ заключается в управлении сокетом над слоем создания сокета.

То есть поток на клиенте должен будет отслеживать сокет, посылая данные (периодически на сервер, что-то вроде «ping» для проверки состояния разорванного канала)), а затем уничтожить (очистить) и заново создать сокет (промыть и повторить), если произойдет ошибка ввода-вывода.

Обратите внимание, что более сложный двунаправленный бит логики будет лучше, если Клиент может обеспечить ожидаемый и непротиворечивый (и своевременный) ответ от Сервера на заданный «пинг».Это конкретно подтвердило бы, что двунаправленный трафик течет.В противном случае межсетевые экраны могут закрывать трафик в одном направлении, в то время как Клиент полагает, что он все еще «общается» с Сервером (который вполне может получать данные, но не может передавать их обратно Клиенту - возможно, вызывая его прекращение.соединение по таймауту неактивности).

0 голосов
/ 21 марта 2012

Когда ваш клиент ловит SocketException, он должен перейти в состояние tryToReconnect . Теперь он проверяет сервер через некоторый интервал (например, 1 сек, может быть, больше, в зависимости от сервера). Убедитесь, что вы реализовали некоторую логику, чтобы остановить это, когда оно больше не нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...