2014-09-05 1 views
2

Я пытаюсь отправить UDP-телеграмму, используя локальную многоадресную рассылку. Я использую Qt, который предлагает QUdpSocket. Я смог сделать это в Linux, но не смог заставить код работать в Windows.Link-local Multicast over QUdpSocket на Windows

Мой первый код выглядел следующим образом:

udp.writeDatagram(QByteArray("hello world"), QHostAddress("FF02::1"), 4321); 

Он работает на Linux, но не на Windows. Я даже попробовал запустить приложение с правами администратора. writeDatagram() возвращает размер телеграммы на обеих системах.

Единственный совет, который я нашел, - это отправить телеграмму на определенный сетевой интерфейс. Мой код для этого подхода:

foreach(const QHostAddress& address, QNetworkInterface::allAddresses()) { 
    udp.bind(address, 0); 

    if(address.protocol() == QAbstractSocket::IPv6Protocol) { 
     udp.writeDatagram(data, QHostAddress("FF02::1"), 4321); 
    } 

    udp.close(); 
} 

Код снова отправляет телеграмму на Linux, но не в Windows. allAddresses() возвращает локальные адреса ссылок IPv6 в обеих операционных системах.

QUdpSocket::joinMulticastGroup() ничего не сделал (как и ожидалось, потому что это касается получения).

Я использую Wireshark (на отправляющей машине и другой машине в сети), чтобы проверить, отправлены ли телеграммы. Чтобы проверить, работает ли сетевой код вообще, я добавил широковещательную передачу IPv4, которая работает в Windows с обоими решениями. Я знаю, что моя Windows поддерживает IPv6, потому что у нее есть локальный адрес ссылки. Брандмауэр Windows был отключен во время тестов, и у меня нет другого брандмауэра, установленного в тестовой системе. Полный тестовый код можно найти here in a Gist.

Почему Windows отказывается отправлять телеграмму? Мой код что-то отсутствует или есть ошибка в Qt? Кто-нибудь заставлял это работать? Пожалуйста помоги.

ответ

1

Второй подход был верным. Мне пришлось open() сокеты снова после close() их. Я предполагаю, что я думал, что это было сделано в bind(), т.к. сокет был открыт после того, как будет создан объект ...

Рабочий код:

foreach(const QHostAddress& address, QNetworkInterface::allAddresses()) { 
    if(address.protocol() == QAbstractSocket::IPv6Protocol) { 
     _udp.bind(address, 0); 
     _udp.writeDatagram(data, QHostAddress("FF02::1"), DISCO_PORT); 

     _udp.close(); 
     _udp.open(QUdpSocket::ReadWrite); 
    } 

}