#java #sockets #udp
Вопрос:
Я создаю приложение типа клиент/сервер, в котором клиент будет отправлять миллионы сообщений. У меня есть поток, цель которого состоит только в отправке пакетов через DatagramSocket. Проблема в том, что прямо сейчас поток вызывает метод send() такого количества типов, что некоторые пакеты отбрасываются по мере заполнения внутреннего буфера отправки.
Есть ли способ на java заблокировать вызов send() объекта DatagramSocket, если буфер уже заполнен, чтобы не отбрасывать пакеты?
Комментарии:
1. Вы знаете, что дейтаграммы все равно не гарантируют доставку? U в UDP говорит вам об этом. Таким образом, расхаживание на стороне отправки не обязательно является полным решением.
2. Ты лаешь не на то дерево. Пакеты не отбрасываются, потому что буфер отправки заполнен. Это приводит
DatagramSocket.send()
к блокировке . Смотрите Javadoc. Пакеты отбрасываются, потому что UDP может отбросить их в любое удобное для него время в любом месте сети, включая отправляющий хост, любые промежуточные маршрутизаторы и принимающий хост. Либо ускорьте свой приемник , либо не отправляйте так быстро, либо и то, и другое, либо используйте надежный протокол с ускорением.
Ответ №1:
Вы можете использовать канал DatagramChannel вместо непосредственного создания сокета.
Канал может быть установлен в режим блокировки, который, согласно описанию отправки, означает, что вызов будет ждать, пока освободится буферное пространство.
Комментарии:
1. Обратите внимание, что это не устраняет необходимость в ускорении передачи, чтобы предотвратить отправку данных так быстро, что дейтаграммы будут отброшены.
2. @DavidSchwartz — Верно, опять эта буква «U» в» UDP». Любой, кто встретится на пути, может сбросить дейтаграмму. (И это также указывает на необходимость тестирования через Интернет, а не только в односегментной локальной сети).
3. Это не решение проблемы. Это вообще не имеет никакого значения.
DatagramSocket
уже находится в режиме блокировки, поэтому у него уже есть точно такое же свойство. NB «U» в UDP означает «Пользователь», а не «Ненадежный». Смотрите RFC.4. А, ладно. Я поверил оператору на слово, что проблема такова, как описано.
5. Проблема с вашим ответом не в ложном предположении ОП: это полное отсутствие какой-либо разницы в этом отношении между
DatagramSocket.send()
блокировкой и блокировкойDatagramSocketChannel.send()
.