从广播中获取答案

Get answers from broadcast

我正在使用 Poco::Net::DatagramSocket 实现 WSDiscovery 服务。 这是代码:

string OnvifCamera::_sendFullProbe_for_Discovery() const noexcept
{
    Poco::Net::DatagramSocket ss(Poco::Net::IPAddress::IPv4);
    Poco::Net::SocketAddress sa(global.getDiscoveryIP(), global.getDiscoveryPort()); //IP "239.255.255.250", port 3702
    try
    {
        auto msg = _createXML_for_FullProbe();//is the XML probe x discovery
        ss.sendTo(msg.data(), msg.size(), sa);
    }
    catch (const Poco::IOException& ex)
    {
        cerr<<"\nException: "<<ex.what()<<", "<<ex.displayText()<<endl;
        return string();
    }
    ss.setBroadcast(true);

    char buffer[4096];
    int n = ss.receiveBytes(buffer, sizeof(buffer));
    cout<<"Got "<<n<<" bytes"<<endl;
    ss.close();
    return string(buffer);
}

每个设备(IP Onvif 摄像头)都会用他的 XML 数据回答。

问题是如果我有更多的摄像头,我只能得到1个摄像头的答案。我怎样才能得到所有的答案?

您只拨打了 receiveBytes 一次电话,因此您只得到一个答复。

要收到多个单独的答案,您需要反复调用 receiveBytes,并且很可能会实施超时,之后您将放弃等待收到更多回复(因为您不知道apriori 会有多少)。

按照@Alnitack 的建议,这是代码(有效):

vector<XMLString> OnvifDiscovery::_sendFullProbe_for_Discovery() noexcept
{
    vector<XMLString> cameras_XML;
    DatagramSocket ss(IPAddress::IPv4);
    SocketAddress sa(_global.getDiscoveryIP(), _global.getDiscoveryPort());
    try
    {
        auto msg = _createXML_for_FullProbe();
        ss.sendTo(msg.data(), msg.size(), sa);
    }
    catch (const IOException& ex)
    {
        cerr<<"\nException: "<<ex.what()<<", "<<ex.displayText()<<endl;
        return cameras_XML;
    }

    ss.setBroadcast(true);

    Poco::Timespan timespan(2500000);
    ss.setReceiveTimeout (timespan);
    try {
        for(;;)
        {
            array<char, 4096> buffer {'[=10=]'};
            int n = ss.receiveBytes(buffer.data(), sizeof(buffer));
            //cout<<"Received "<<n<<" bytes"<<endl;
            cameras_XML.push_back(buffer.data());
        }
    }
    catch(const Poco::TimeoutException &ex)
    {
        cout<<"Timeout:"<<ex.what()<<endl;
    }
    cout<<cameras_XML.size()<<endl;
    ss.close();
    return cameras_XML;
}