Неблокирующий UDP-ввод / вывод vs блокировка UDP-ввода / вывода в Java

неблокирующий TCP / IP SocketChannels и Selector в NIO помогите мне обрабатывать многие TCP / IP-соединения с небольшим количеством потоков. Но как насчет UDP DatagramChannels? (Должен признаться, что я не очень хорошо знаком с UDP.)

операции отправки UDP не блокируются, даже если DatagramChannel не работает в блокирующем режиме. Есть ли действительно случай, когда DatagramSocket.send(DatagramPacket) блоки из-за пробок или что-то подобное? Мне очень интересно, есть ли такой случай и какие возможные случаи существуют в производственная среда.

если DatagramSocket.send(DatagramPacket) фактически не блокируется, и я не собираюсь использовать connected DatagramSocket и привязка только к одному порту, нет ли преимущества использования неблокирующего режима с DatagramChannel и Selector?

3 ответов


прошло некоторое время с тех пор, как я использовал DatagramSockets Java, каналы и тому подобное, но я все еще могу вам помочь.

протокол UDP не устанавливает соединение, как это делает TCP. Скорее, он просто отправляет данные и забывает о них. Если важно убедиться, что данные действительно попадают туда, это ответственность клиента. Таким образом, даже если вы находитесь в режиме блокировки, ваша операция отправки будет блокировать только до тех пор, пока не очистит буфер. Поскольку UDP ничего не знает о сети, он запишет его при первой возможности, не проверяя скорость сети или если он действительно доберется туда, куда он должен идти. Таким образом, вам кажется, что канал на самом деле сразу готов к дополнительной отправке.


UDP не блокирует (он блокирует только при передаче данных в ОС) Это означает, что если в любой момент следующий переход/коммутатор/машина не может буферизировать UDP-пакет, он отбрасывает его. Это может быть желательным поведением в некоторых ситуациях. Но это то, что вы должны знать.

UDP также не гарантирует

  • доставка пакетов в порядке их отправки.
  • не разбивать большие пакеты.
  • пересылка пакетов через коммутаторы. Часто переадресация UDP между коммутаторами отключена.

однако UDP поддерживает многоадресную рассылку, поэтому один и тот же пакет может быть доставлен на один или несколько хостов. Отправитель понятия не имеет, получает ли кто-нибудь пакеты.

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


Non преграждая UDP главным образом полезно на получая стороне. Отправка пакетов может быть отложена только из-за местных обстоятельств: локальные инструменты формирования трафика, такие как "игровые сетевые карты", которые приоритизируют игровой трафик над другими источниками трафика, или перегруженная сетевая карта (что вряд ли произойдет) может задержать отправку пакета. После выхода из системы. Как только пакет покидает локальный интерфейс, это больше не забота приложения.