Повторно подключите соединение через сокет Java при отключении - PullRequest
6 голосов
/ 05 июня 2009

У меня есть Java-код, который устанавливает долговременное сокетное соединение с устройством домашней автоматизации, чтобы отслеживать его активность / события. Проблема заключается в том, что если устройство перезагружается или отключается питание, код Java должен автоматически подключаться как можно скорее. Любые идеи о том, как обнаружить потерянное соединение на стороне Java, желательно без периодического опроса устройства?

Ответы [ 3 ]

3 голосов
/ 05 июня 2009

Если устройство перезагружается без надлежащего закрытия сокета, я не знаю ничего, что позволило бы его обнаружить. В этом случае ваш сервер не сможет обнаружить, что сокет пропал, если только устройство не восстановится или пока стек TCP / IP на вашем сервере не сдастся и не объявит, что соединение не работает. В какой-то момент вы получите IOException.. Вам нужно перехватить это исключение, а затем снова подключиться, когда это произойдет.

Вы действительно зависите от поведения TCP / IP здесь. Когда один конец соединения просто исчезает (без пакета FIN), другой конец может ждать произвольный промежуток времени (в зависимости от многих факторов), прежде чем решить, что соединение разорвано.

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

2 голосов
/ 07 июня 2009

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

Чтобы сделать это, просто вызовите метод setKeepAlive (true) для сокета, и это заставит базовую реализацию сокета включить опцию SO_KEEP_ALIVE.

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

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

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

1 голос
/ 18 февраля 2011

Я решил точно такую ​​же проблему.

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

Цитируется сверху:

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

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