C++ UDP RecvFrom, отправка в разные сокеты

я написал многопоточный UDP-сервер по следующей схеме:

Схема: 1 поток-получатель (несколько рабочих потоков, каждый из которых имеет собственный сокет, а не привязку, только что созданный Ipv4, UDP, дейтаграмму). Сообщение передается 1 рабочему потоку, который затем обрабатывает его, а затем отправляет ответ со своим собственным сокетом.

Проблема: это отлично работает во всех моих собственных тестовых программах, но по какой-то странной причине не работает со старым программным обеспечением, для которого я эмулирую сервер. Программное обеспечение использует асинхронный Wsa (перекрывается), но я до сих пор не понимаю, почему он не работает.

Путаница: это работает, если я использую тот же сокет для отправки, что и для получения данных на стороне сервера. Я не понимаю, почему udp - это протокол без установления соединения, так как же он может обнаружить другой сокет?


person L. Terrat    schedule 13.01.2018    source источник
comment
Может ли быть связано с брандмауэром? Различные сокеты означают разные пары адрес/номер порта. Брандмауэр может обнаружить это и пометить как подозрительный.   -  person Some programmer dude    schedule 14.01.2018
comment
Это на локальном хосте, поэтому я не думаю, что это связано с брандмауэром.   -  person L. Terrat    schedule 14.01.2018


Ответы (1)


Путаница: это работает, если я использую тот же сокет для отправки, что и для получения данных на стороне сервера. Я не понимаю, почему udp - это протокол без установления соединения, так как же он может обнаружить другой сокет?

Если вы посмотрите на заголовки UDP пакетов, которые вы отправляете, вы заметите, что они содержат поле «Порт источника UDP». Это поле может быть проверено получателем пакета (через recvfrom()), чтобы узнать, какой порт UDP используется отправляющим сокетом UDP на машине-отправителе (обратите внимание, что это отличается от поля «UDP Destination Port», которое определяет, какой порт пакет должен быть доставлен на принимающей машине). Возможно, в вашем случае программа, с которой вы общаетесь, просматривает это поле и корректирует свое поведение на основе значения этого поля.

Если вам интересно, какое значение будет установлено в этом поле, если вы никогда не вызывали bind() для отправляющего сокета UDP, ответ заключается в том, что ОС выберет доступный номер порта UDP для отправки (по сути, неявный метод bind()).

person Jeremy Friesner    schedule 13.01.2018
comment
AFAIK только путем явной привязки сокета (ов) к этому порту. (Возможно привязать несколько сокетов к одному порту UDP, вызвав setsockopt(fd, SOL_SOCKET, SO_REUSEADDR) и/или setsockopt(fd, SOL_SOCKET, SO_REUSEPORT) для сокетов перед выполнением для них bind(), но обратите внимание, что с несколько сокетов, привязанных к одному и тому же порту, будет неопределенным, какой сокет получает любые входящие пакеты UDP) - person Jeremy Friesner; 14.01.2018