NIO Java: Что делает IOException: Поврежденный средний канал? [дубликат]

Другой взгляд на ответ Даррона , вот как я это делаю:

IN="bla@some.com;john@home.com"
read ADDR1 ADDR2 <<<$(IFS=";"; echo $IN)

89
задан MC Emperor 8 March 2014 в 10:24
поделиться

3 ответа

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

Если вы используете неблокирующий режим, тогда метод SocketChannel.connect вернет false, и вам нужно будет использовать isConnectionPending и finishConnect, чтобы убедиться, что соединение установлено. Я обычно кодирую, основываясь на ожидании, что все будет работать, а затем перехватываю исключения для обнаружения сбоя, вместо того, чтобы полагаться на частые вызовы "isConnected".

23
ответ дан 24 November 2019 в 07:19
поделиться

Что вызывает "обрыв канала" и, что более важно, возможно ли выйти из этого состояния?

Это вызвано чем-то, вызывающим закрытие соединения. (Это не ваше приложение закрыло соединение: это привело бы к другому исключению.)

Невозможно восстановить соединение. Вам нужно открыть новый.

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

Да, это так. Как только вы получите это исключение, сокет больше не будет работать. Его закрытие - единственное разумное решение.

Будет ли когда-нибудь такое IOException , когда соединение сокета все еще подключается должным образом в первую очередь (а не рабочее соединение, которое не удалось в какой-то момент)?

Нет. (Или, по крайней мере, не без нарушения правильного поведения сетевого стека ОС, JVM и / или вашего приложения.)


Разумно ли всегда вызывать SocketChannel.isConnected () перед попыткой SocketChannel.write () ...

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

В этом конкретном случае вызов isConnected () бессмыслен. Метод определен так, чтобы возвращать истину , если сокет был подключен в какой-то момент в прошлом . Он не сообщает вам, активно ли соединение. Единственный способ определить, активно ли соединение, - это попытаться его использовать; например, выполните чтение или запись.

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

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

98
ответ дан 24 November 2019 в 07:19
поделиться

Вы должны предположить, что сокет был закрыт на другом конце. Оберните свой код блоком try catch для IOException.

Вы можете использовать isConnected (), чтобы определить, подключен ли SocketChannel или нет, но это может измениться до завершения вашего вызова write (). Попробуйте вызвать его в своем блоке catch, чтобы узнать, действительно ли именно поэтому вы получаете исключение IOException.

1
ответ дан 24 November 2019 в 07:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: