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

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

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

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

9 Solutions collect form web for “Java обнаруживает потерянное соединение”

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

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

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

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

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

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

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

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

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

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

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

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

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

Хорошо, поэтому я, наконец,

 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 ().

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

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

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

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

Нил

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

 boolean connected = socket.isConnected() && !socket.isClosed(); 
  • Запустить командный файл с командой psql без пароля
  • «Основное соединение было закрыто: при отправке произошла непредвиденная ошибка». С SSL-сертификатом
  • В чем разница между соединением и таймаутом чтения для сокетов?
  • Какой порт используется соединением Java RMI?
  • Загрузка JSON с NSURLSession не возвращает никаких данных
  • Можно ли использовать статический экземпляр java.sql.Connection в многопоточной системе?
  • Почему при запуске URL-адреса возникает исключение «java.net.ConnectException: Connection timed out»?
  • mySQL - создание новой таблицы с использованием данных и столбцов из трех таблиц
  • Interesting Posts

    Скрытые особенности JSP / Servlet

    Android sp vs dp text – что бы регулировать «масштаб» и что является философией поддержки

    sqlbulkcopy с использованием sql CE

    Скрыть расширение / свернуть символ или деактивировать спецификацию. строки в jqGrid subgrid

    Рельсы, расширяющие ActiveRecord :: Base

    Связывание / группировка файла с папкой в ​​Windows, так что они оба перемещаются вместе

    Не удается выполнить миграцию базы данных после эшафота. Раздел 2.2 Учебник по Ruby on Rails Майкл Хартл

    Разница между передачей массива и указателем на функцию в C

    Отключить диалог «Сохранить изменения» в Adobe Reader

    Что такое «= C2 = A0» в MIME-кодированном, цитируемом тексте?

    Как имитировать параллельный (LPT) принтер с USB-принтером?

    Как взаимодействовать с устройствами, имеющими один и тот же IP-адрес

    Не нужно ли добавлять super () в конструктор?

    Лучший способ рандомизировать массив с .NET.

    В чем разница между режимами Release и Debug в Visual Studio?

    Давайте будем гением компьютера.