NIO: отправить сообщение, а затем немедленно отключиться - PullRequest
3 голосов
/ 03 февраля 2010

В некоторых случаях я хочу отправить сообщение об ошибке с сервера клиенту, используя неблокирующий ввод / вывод (SocketChannel.write(ByteBuffer)), а затем отключить клиент. Предполагая, что я напишу полное содержание сообщения, а затем немедленно отключусь, я предполагаю, что клиент может не получить это сообщение, так как я предполагаю, что ОС на самом деле не отправила данные в этот момент.

Это правильно, и если да, то есть ли рекомендуемый подход к решению этой ситуации?

Я думал об использовании таймера, при котором, если я хочу отключить клиента, я отправляю сообщение, а затем через 1-2 секунды закрываю его соединение.

Ответы [ 3 ]

1 голос
/ 03 февраля 2010

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

Если вам действительно нужно убедиться, чтоСообщение об ошибке отправляется клиенту перед отключением сокета, я бы просто включил блокировку перед вызовом метода записи.Используя неблокирующий режим, вам придется вызывать запись в цикле, подсчитывая количество байтов, отправляемых каждым вызовом, и выходить из цикла, когда вам удалось передать все сообщение в сокет (плохое решение, я знаю,ненужный код, занятое ожидание и т. д.).

0 голосов
/ 18 января 2012

Метод сокетов close() гарантирует, что все, что было отправлено с помощью write before, действительно отправляется до того, как сокет действительно закрыт.Однако это предполагает, что ваш write() смог скопировать все данные в окно вывода стеков tcp, что не всегда будет работать.Для решения этого см. Другие ответы.

0 голосов
/ 05 февраля 2010

вам лучше запустить поток и синхронно записать данные в канал.async api больше ориентирован на «один поток, отправляющий несколько каналов» и на самом деле не предназначен для запуска и забывания сообщений.

...