Подтвердить что ты не робот

Java обнаруживает потерянное соединение

Когда я использую, например, PuTTY и мое соединение теряется (или когда я делаю руководство ipconfig /release в Windows), он отвечает напрямую и уведомляет, что мое соединение было потеряно.

Я хочу создать программу Java, которая контролирует мое подключение к Интернету (на какой-то надежный сервер), чтобы регистрировать дату/время, когда мой интернет терпит неудачу.

Я попытался использовать метод Socket.isConnected(), но навсегда вернет "true". Как это сделать в Java?

4b9b3361

Ответ 1

Хорошо, лучший способ узнать, прерывается ли ваше соединение, - попытаться прочитать/записать из сокета. Если операция завершилась неудачно, вы потеряли соединение когда-нибудь.

Итак, все, что вам нужно сделать, это попытаться прочитать с некоторым интервалом, и если сбой чтения не попытается повторно подключиться.

Важные события для вас будут, когда сбой чтения - вы потеряли соединение, а когда подключен новый сокет, вы восстановили соединение.

Таким образом, вы можете отслеживать время и время простоя.

Ответ 2

Несмотря на то, что протокол TCP/IP является "ориентированным на соединение", как правило, никакие данные не отправляются по незанятому соединению. Вы можете открыть сокет в течение года без одного бита, переданного по нему IP-стеком. Чтобы заметить, что соединение потеряно, вам необходимо отправить некоторые данные на уровне приложения. (*) Вы можете попробовать это, отключив телефонный кабель от вашего ADSL-модема. Все подключения на вашем ПК должны оставаться на месте, если только приложения не имеют какого-либо механизма keepalive на уровне приложений.

Таким образом, единственный способ заметить потерянное соединение - открыть TCP-соединение с некоторым сервером и прочитать некоторые данные из него. Возможно, самым простым способом может быть подключение к некоторому FTP-серверу и выборка небольшого файла - или списка каталогов - время от времени. Я никогда не видел общий сервер, который действительно предназначался для использования в этом случае, и владельцам FTP-сервера могут не нравиться клиенты, делающие это.

(*) Существует также механизм, называемый TCP keepalive, но во многих ОС вы должны активировать его для всех приложений, и это не очень удобно использовать, если вы хотите быстро заметить потерю соединения.

Ответ 3

Почему бы не использовать метод isReachable() класса java.net.InetAddress?

Как это работает, это конкретная реализация JVM, но:

Типичная реализация будет использовать ICMP ECHO REQUESTs, если эта привилегия может быть получена, в противном случае она попытается установить TCP-соединение на порте 7 (Echo) целевого хоста.

Если вы хотите постоянно открывать соединение, чтобы вы могли видеть, когда это не удается, вы можете скорее подключиться к серверу, на котором выполняется

Ответ 4

Если клиент правильно отсоединился, a read() вернет -1, readLine() возвращает null, readXXX() для любых других бросков X EOFException. Единственным надежным способом обнаружения потерянного TCP-соединения является запись на него. В конце концов, таким образом, будет выведено IOException 'соединение reset', но из-за буферизации требуется не менее двух записей.

Ответ 5

Возможно, вы захотите посмотреть на сокет интервал времени ожидания. С небольшим таймаутом (я считаю, что по умолчанию это "бесконечный тайм-аут" ), тогда вы можете уловить исключение или что-то, когда хост станет недоступным.

Ответ 6

Хорошо, поэтому я, наконец, начал работать с

try
{
    Socket s = new Socket("stackoverflow.com",80);
    DataOutputStream os = new DataOutputStream(s.getOutputStream());
    DataInputStream is = new DataInputStream(s.getInputStream());
    while (true)
    {
        os.writeBytes("GET /index.html HTTP/1.0\n\n");
        is.available();
        Thread.sleep(1000);
    }
}
catch (IOException e)
{
    System.out.println("connection probably lost");
    e.printStackTrace();
}

Не так чисто, как я надеялся, но он не работает, если я не укажу os.writeBytes().

Ответ 7

Метод isConnected() внутри класса Socket.java немного вводит в заблуждение. Он не говорит вам, подключен ли сокет к удаленному хосту (например, если он не закрыт). Вместо этого он сообщает вам, был ли сокет когда-либо подключен к удаленному хосту. Если сокет смог подключиться к удаленному хосту вообще, этот метод возвращает true, даже после того, как этот сокет был закрыт. Чтобы узнать, открыт ли сокет, вам нужно проверить, что isConnected() возвращает true и isClosed() возвращает false. Например:

boolean connected = socket.isConnected() && !socket.isClosed();

Ответ 8

Вы можете пинговать машину каждые несколько секунд, и это было бы довольно точно. Будьте осторожны, чтобы вы не сделали DOS.

Другой альтернативой будет запуск небольшого сервера на удаленном компьютере и сохранение связи с ним.

Ответ 9

Возможно, проще подключиться к yahoo/google или где-то в этом роде.

    URL yahoo = new URL("http://www.yahoo.com/");
    URLConnection yc = yahoo.openConnection();
    int dataLen = yc.getContentLength() ;

Neil