Это уже какое-то время сводит меня с ума. Поскольку я никогда не делал никакого кода, связанного с сетью, я не могу подвести итоги этого эксперимента.
Мне предоставлена информация о сервере, который передает соответствующую информацию с помощью SSDP. Мне дали IP и порт согласно стандарту. Мне также дали запрос и цель поиска, которые мне нужно использовать на стороне получателя. Я использую свою последнюю итерацию для этого примера, в которой я решил использовать одноэлементный класс, который управляет обнаружением. Настоящая строка ST, которую я использую, тоже была предоставлена мне, не обращайте внимания на приведенную ниже ...
DiscoveryManager.h
class DiscoveryManager : public QObject
{
private:
DiscoveryManager( QObject *parent=0 );
public:
~DiscoveryManager();
// Public Accessor for the singleton instance of the class
static DiscoveryManager* Instance();
void Discover();
public:
void readPending();
private:
// Singleton instance of the class
static DiscoveryManager* _instance;
QUdpSocket* socket;
};
DiscoveryManager.cpp
// Definition of singleton instance
DiscoveryManager* DiscoveryManager::_instance;
// Network Parameters
quint16 port = 1900;
QHostAddress groupAddress = QHostAddress("239.255.255.250");
DiscoveryManager::DiscoveryManager(QObject *parent)
: QObject(parent)
, socket( nullptr )
{
socket = new QUdpSocket(this);
auto ok = m_sock->bind(QHostAddress::AnyIPv4, port, QUdpSocket::ShareAddress);
if (!ok)
{
printf("Bind Error\n");
return;
}
ok = socket->joinMulticastGroup(groupAddress);
if (!ok) {
printf("Join Multicast Group Failed\n");
return;
}
connect(socket, SIGNAL(readyRead()), this, SLOT(readPending()));
}
DiscoveryManager* DiscoveryManager::Instance()
{
if (_instance == nullptr)
{
_instance = new DiscoveryManager();
}
return _instance;
}
void
DiscoveryManager::startDiscovery()
{
QByteArray message("M-SEARCH * HTTP/1.1\r\n" \
"HOST: 239.255.255.250:1900\r\n" \
"MAN: \"ssdp:discover\"\r\n" \
"MX: 5\r\n" \
"ST: ***:******-****-***:*******:***********:*\r\n" \
"\r\n");
auto writeOk = socket->writeDatagram(message.data(), groupAddress, port);
if (writeOk == -1) {
printf("Writing Datagram failed\n");
return;
}
}
void
DiscoveryManager::readPending()
{
while (socket->hasPendingDatagrams()) {
QByteArray reply;
reply.resize(socket->pendingDatagramSize());
socket->readDatagram(reply.data(), reply.size());
// ... Parse Text Here ...
}
}
Полученные результаты: В 90% случаев это не удается. Когда я пытаюсь распечатать сообщения, получаемый мной ответ всегда является отражением того, что я запрашивал. Независимо от того, как долго я его оставляю, правильный ответ никогда не приходит. С другой стороны, когда условия «самые подходящие», обнаружение безупречно и всегда немедленно возвращает результат.
Ожидаемые результаты: Я ожидаю увидеть ответ сервера с дополнительной информацией, такой как местоположение.
Соображения:





Я столкнулся с аналогичными проблемами на Mac, но с другим кодом на iOS. Вам удалось это исправить? Как?
Что ж, единственный способ получить ответы - это привязка к порту, отличному от 1900, но я не знаю, правильный ли это. Я нашел это с помощью wirehark, например, Google Chrome использует "случайный" порт в качестве исходного порта при отправке M-SEARCH и 1900 в качестве пункта назначения.
Установив порт привязки на 1900, я смог получить только дейтаграммы, отправленные на «239.255.255.250», например, другое программное обеспечение M-SEARCH или сообщения NOTIFY устройств.
Это должно заставить ваш код работать:
auto ok = m_sock->bind(QHostAddress::AnyIPv4, 56123, QUdpSocket::ShareAddress);
Эхо, вероятно, связано с тем, что вы привязаны к прослушиванию на порту 1900, поэтому, когда вы отправляете широковещательную рассылку всем на порт 1900, маршрутизатор отправляет его прямо вам, и вы его получаете. Возможно, это также мешает реальным ответам других устройств в сети?