Неблокирующий UDP-I/O против блокировки UDP-ввода-вывода в Java
Неблокирующие TCP/IP SocketChannels и Selector в NIO помогают мне обрабатывать множество соединений TCP/IP с небольшим количеством потоков. Но как насчет UDP DatagramChannels? (Я должен признать, что я не очень хорошо знаком с UDP.)
Операции отправки UDP, похоже, не блокируются, даже если DatagramChannel не работает в режиме блокировки. Действительно ли случай, когда DatagramSocket.send(DatagramPacket) блокируется из-за перегруженности или чего-то подобного? Мне действительно интересно, есть ли такой случай и какие возможные случаи существуют в производственной среде.
Если DatagramSocket.send(DatagramPacket) фактически не блокируется, и я не собираюсь использовать подключенный DatagramSocket и привязываться только к одному порту, нет ли преимущества использования неблокирующего режима с DatagramChannel и Selector?
Ответы
Ответ 1
Прошло некоторое время с тех пор, как я использовал Java DatagramSockets, Channels и т.п., но я все равно могу вам помочь.
Протокол UDP не устанавливает соединение, такое как TCP. Скорее, он просто отправляет данные и забывает об этом. Если важно убедиться, что данные фактически попадают туда, это ответственность клиента. Таким образом, даже если вы находитесь в режиме блокировки, ваша операция отправки будет блокироваться только до тех пор, пока требуется сброс буфера. Так как UDP ничего не знает о сети, он будет записывать его при первой же возможности, не проверяя скорость сети, или если он действительно доберется до того места, где он должен идти. Таким образом, вам кажется, что канал действительно готов к дальнейшей отправке.
Ответ 2
UDP не блокируется (он блокируется только при передаче данных в ОС)
Это означает, что если в какой-либо момент следующий hop/switch/machine не может буферизовать пакет UDP, он опустит его. Это может быть желательным поведением в некоторых ситуациях. Но это то, о чем вам нужно знать.
UDP также не гарантирует
- пакеты доставки в том порядке, в котором они отправлены.
- не разбивать большие пакеты.
- пересылать пакеты через коммутаторы. Часто переадресация UDP между коммутаторами отключается.
Однако UDP поддерживает многоадресную рассылку, поэтому один и тот же пакет может быть доставлен на один или несколько хостов. Отправитель не имеет понятия, получает ли кто-либо пакеты.
Сложная вещь в UDP - это работает большую часть времени, но иногда бывает неудачно, что очень трудно воспроизвести. По этой причине вы не должны полагаться на надежность, даже если выполняете несколько тестов и, похоже, работаете.
Ответ 3
Неблокирующий UDP в основном полезен на принимающей стороне.
Отправка пакетов может быть отложена только из-за локальных обстоятельств: инструменты локального трафика, такие как "игровые сетевые карты", которые определяют приоритетность игрового трафика по другим источникам трафика или перегруженную сетевую карту (что вряд ли произойдет), могут задержать отправку пакета. Выйдя из системы. Когда пакет покидает локальный интерфейс, это больше не касается приложения.