Как может Socket.close () завершиться ошибкой (исключение не выдается)? - PullRequest
3 голосов
/ 20 июня 2011

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

Я подтвердил в отладчике, что на самом деле происходит вызов close().Кроме того, это не исключение.Тем не менее, сокет сообщает о подключении.Я знаю, потому что есть другая нить wait для отключения.Этот поток должен позже повторно подключить его, но этого не происходит, потому что вызов isConnected() продолжает возвращать true.

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

Если вы звоните Socket.close(), есть ли способ, который может молча провалиться?

Ответы [ 5 ]

6 голосов
/ 20 июня 2011

isConnected не означает, что "подключен к серверу" , но "был подключен" . Используйте isClosed, если хотите знать, была ли розетка закрыта.

2 голосов
/ 20 июня 2011

isConnected() не означает, что вы думаете.Я всегда буду оставаться верным после того, как вы подключитесь, если я правильно запомню.

Редактировать: Из документации :

true if the socket successfuly connected to a server

Это означаетчто это не станет ложным, когда вы отключитесь.

Edit2: я видел, что некоторые другие ответы рекомендуют вам проверить isClosed.Обратите внимание, что isClosed возвращает true, только если вы вызвали close().Он не начнет автоматически возвращать истину, если другая сторона закроет соединение.

1 голос
/ 20 июня 2011

Сочетая комментарии артбристола, ответы Кая и Доус и некоторые дополнительные диагностики, которые я сделал, полный ответ:

  1. close(), вероятно, не не удалось.Вы не можете проверить текущее состояние соединения сокета с помощью isConnected(), это только говорит вам, если когда-либо было успешное соединение.Позвонив на isClosed(), вы узнаете, звонили ли close() на вашу сторону раньше.

  2. При отладке анализатор пакетов может показать вам, что действительно происходит на проводе, когда вы проходите черезкод.Для вашего примера это должно показать, что соединение действительно закрывается на сетевом уровне, т. Е. Вы должны увидеть FIN и соответствующие пакеты ACK, а затем не более.

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

0 голосов
/ 28 февраля 2017

Кто-нибудь пришел сюда и интересуется, как проверить, закрыто ли Socket.

socket.isConnected() && socket.isClosed()
0 голосов
/ 20 июня 2011

Я не знаю ни о каком таком поведении. Возможно, второму потоку повезет больше, если он позвонит isClosed?

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