Как узнать статус уже установленного соединения? - PullRequest
0 голосов
/ 27 октября 2011

Я видел несколько вопросов, касающихся этого, но никогда не сталкивался с решением, которое выполнимо в моей ситуации. У меня есть 2 устройства связи, которые общаются через мое прокси-устройство. Я хочу знать, как я могу периодически проверять состояние соединения. Прокси-программы находятся в Java. Методы isClosed () и т. Д. Не будут служить этой цели. Я обнаружил, что чтение из потока не столь эффективно (http://www.codeproject.com/Articles/37490/Detection-of-Half-Open-Dropped-TCP-IP-Socket-Conne.aspx), и выполнение записи в буферизованные потоки может быть эффективным. Но мое ограничение заключается в том, что фактический клиент и серверы неприкасаемы (код C коммуникационная часть не может быть изменена). Поэтому я хочу знать, есть ли альтернативный способ проверить потерянное соединение.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 27 октября 2011

Недавно я столкнулся с той же проблемой и пришел к выводу, что самым чистым решением будет отправка «пустых» TCP-пакетов, то есть пакетов с длиной полезной нагрузки 0. Это приведет к тому, что стек TCP другого конца будет просто отправьте ACK, не уведомляя приложение на другой стороне, что снова позволяет локальному стеку TCP определить, живо ли соединение.

К сожалению, Java (Sun / Oracle SDK) не предоставляет никаких средств для отправки пустых пакетов; write(new byte[0]); не будет работать.

В моем случае я, кажется, нашел возможное решение:

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

Учитывая, что данные "OOB" редко когда-либо используются, а иногда реализуются только наполовину - как в Java - кажется вероятным, что использование этого "трюка" не помешает большинству приложений.

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

0 голосов
/ 27 октября 2011

Сокет не может знать, что происходит между его локальной и удаленной конечными точками, не без какой-либо связи, чтобы установить, действительно ли между конечными точками есть действительное соединение. Единственный способ узнать, живо ли соединение, - это использовать какое-то сообщение ping , на которое ответит приложение на другом конце. Это сообщение ping может фактически представлять собой сообщение любого типа, например опрос данных или любое другое сообщение, которое может быть отправлено без дополнительных эффектов.

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

...