C++ Qt:SSDP和QUdpSocket在极少数情况下有效

C++ Qt:SSDP和QUdpSocket在极少数情况下有效,c++,qt,networking,udp,ssdp,C++,Qt,Networking,Udp,Ssdp,这件事已经让我发疯好一阵子了。因为我从未做过任何与网络相关的代码,所以我无法得出这个实验的结果 我获得了有关使用SSDP广播相关信息的服务器的信息。我按照标准获得了IP和端口。我还得到了需要在接收方使用的查询和搜索目标。我在这个例子中使用了我最新的迭代,在这个例子中,我决定使用一个管理发现的单例类。我使用的真正ST字符串也是我提供的字符串,忽略下面的字符串 DiscoveryManager.h DiscoveryManager.cpp 结果:90%的情况下,此操作失败。当我试图打印消息时,得到的

这件事已经让我发疯好一阵子了。因为我从未做过任何与网络相关的代码,所以我无法得出这个实验的结果

我获得了有关使用SSDP广播相关信息的服务器的信息。我按照标准获得了IP和端口。我还得到了需要在接收方使用的查询和搜索目标。我在这个例子中使用了我最新的迭代,在这个例子中,我决定使用一个管理发现的单例类。我使用的真正ST字符串也是我提供的字符串,忽略下面的字符串

DiscoveryManager.h

DiscoveryManager.cpp

结果:90%的情况下,此操作失败。当我试图打印消息时,得到的响应总是我所查询内容的回音。不管我离开多久,正确的回答永远不会到来。另一方面,当条件“恰到好处”时,发现是完美的,总是立即返回结果

预期结果:我希望看到服务器响应,其中包含更多信息,如位置

注意事项:

  • 因为我很难理解网络相关代码失败的原因,所以我无法从结果中断定我的接收器代码是否正确,或者服务器是否设置正确。我可以使用什么指标?空间中设置的VPN等因素会影响这一点吗?服务器是否在我的本地计算机上运行有关系吗
  • 我已经经历了多次迭代,尝试使用不同的连接标志,在再次尝试之前销毁并重置对象或套接字,甚至执行了一个循环,该循环将查询5000多次以了解行为
  • 如果这段代码看起来不一样,我已经尝试过复制Qt文档提供的完全相同的代码和顺序

  • 我在Mac上遇到了类似的问题,但在iOS上的代码不同。 你把它修好了吗?怎么做

    我得到响应的唯一方法是绑定到1900以外的端口,但我不知道这是否正确。 我使用wireshark发现了这一点,例如Google Chrome在发送M-SEARCH时使用“随机”端口作为源端口,1900作为目标端口

    通过将绑定端口设置为1900,我只能获得发送到“239.255.255.250”的数据报,例如其他软件M-SEARCH或设备通知消息

    这有助于使您的代码正常工作:

    auto ok = m_sock->bind(QHostAddress::AnyIPv4, 56123, QUdpSocket::ShareAddress);
    

    回音可能是因为您绑定在端口1900上收听,所以当您向端口1900上的每个人发送广播时,路由器会直接将其发送回您,您就会收到它。这是否也可能干扰网络上其他设备的实际响应?
    // 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 ...
        }
    }
    
    auto ok = m_sock->bind(QHostAddress::AnyIPv4, 56123, QUdpSocket::ShareAddress);