2016-09-23 5 views
3

Когда я работаю на UDP-сервере, я обычно устанавливаю сокет для прослушивания на указанном порту и принимает любой IP-адрес. Имейте в виду, что прием синхронизации работает здесь правильно.Boost Asio UDP сервер устанавливает сокет для прослушивания по указанному IP

std::unique_ptr<boost::asio::ip::udp::socket> socketUDP;  
socketUDP.reset(new udp::socket(io_serviceUDP, udp::endpoint(udp::v4(), 9999))); 

Однако, я действительно хотел бы иметь 2 различных серверных приложений прослушивания в тот же порт (9999), но принимать только один IP (я уже знаю, что IP). Каждый из приложений имеет свой собственный клиент с собственным IP-адресом. Но по какой-то причине следующее не работает (не принимает никаких пакетов в приложении, в то время как Wireshark можно увидеть)

socketUDP.reset(new udp::socket(m_io_serviceUDP, udp::endpoint(asio::ip::address::from_string("169.254.1.2"), 9999))); 

Обратите внимание: 1) Согласно ответу на: Issue with broadcast using Boost.Asio это должно действительно работать. Конечно, я понимаю, это не совсем верно, как я что-то

2) Предоставленный IP является действительным отсутствует, работает, передает данные (подтвержденное Wireshark) и может быть пингуется

+0

ли у вас это работает сейчас? Я использую образец для многоадресной передачи UDP от Boost 1.66, и он работает. – CaTx

ответ

1

Вопрос заключается в том, что ваши socketUDP «s не настроены с:

set_option(boost::asio::ip::udp::socket::reuse_address(true)); 

Однако, просто позвонив в линию выше на ваших сокетами не будет работать, потому что вы должны вызвать reuse_addressперед тем сокет привязан к конечной точке ... Но вы строите udp::socket с endpoint, который открывает его и связывает его с конечной точкой, см. basic_datagram_socket.

Решение заключается в вызове конструктора, который просто принимает io_service; открыть, установить reuse_address вариант и затемbind его, например .:

// construct the socket 
boost::asio::ip::udp::socket socket_(io_service_); 

// open it 
boost::asio::ip::udp::endpoint rx_endpoint_(udp::v4(), 9999); 
socket_.open(rx_endpoint_.protocol(), error); 
if (error) 
    return false; 

// then set it for reuse and bind it 
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true)); 
socket_.bind(rx_endpoint_, error); 
if (error) 
    return false; 

// set multicast group, etc. 
socket_.set_option(boost::asio::ip::multicast::join_group(ip_address)); 
... 
+0

Я думаю, что это действительно замечательный комментарий, но он затрагивает проблему, которая случится впоследствии. Сейчас даже один сервер не будет работать с указанным IP-адресом. – Arrr

+0

Мне жаль слышать, что @ Arrr .. Есть какой-то код для приемника 'UDP', который работает (насколько мне известно) [здесь] (https://github.com/kenba/via-httplib/tree/master/включать/через/порт связи). Он задокументирован только для сокетов 'TCP', но просто замените' tcp_adaptor' 'udp_adaptor' и вызовите функцию' receive_multicast'. BTW, какой порт вы слушаете: '9999' или' 4747'? – kenba