多网卡的QUdp 组播监听

局域网中提供一个服务,比如提供Qt RO网络中的注册中心的url, 可以考虑使用组播技术.

对于多网卡来说, udp加入组播地址,并绑定端口后,不一定能够收到客户端发送的查询消息,估计是因为消息所在的网络不一定就是绑定的网卡所在的网络,在虚拟机上测试时,会出现这种情况.

现象重现: 服务端在本机上执行, 客户端在虚拟机上执行,客户端向组播地址发送的消息,在NAT模式下,因为ip地址不在同一个网段,数据包不会继续传递,就会造成这种现象

解决的思路就是用每一个网口绑定一个udp就行.
迭代网口,如果网卡激活:IsUp,并且能够组播 CanMulticast,而且不是回环 interface.name().contains(“loopback”),那就构造一个udp,并使用该网卡进行绑定,加入组播

#include "widget.h"
#include "ui_widget.h"

#include 
#include 
#include 
#include 
#define qout qDebug() << __FILE__ << __LINE__
Widget::Widget(QWidget* parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    auto allInterface = QNetworkInterface::allInterfaces();
    for (int i = 0; i < allInterface.size(); ++i) {
        auto interface = allInterface.at(i);
        if (interface.flags() & QNetworkInterface::IsUp) {
            if (interface.flags() & QNetworkInterface::CanMulticast) {
                if (!interface.name().contains("loopback")) {

                    auto udp = new QUdpSocket(this);

                    udp->bind(QHostAddress::AnyIPv4, 62224,
                        QAbstractSocket::ShareAddress | QAbstractSocket::ReuseAddressHint);

                    udp->joinMulticastGroup(QHostAddress("224.2.2.2"), interface);

                    connect(udp, &QUdpSocket::readyRead,
                        this, &Widget::readPendingDatagrams);

                    qout << interface;
                }
            }
        }
    }

    //    auto* timer = new QTimer(this);
    //    connect(timer, &QTimer::timeout, [this] {
    //        this->multiSendMsg();
    //    });
    //    timer->start(5000);
}

Widget::~Widget() { delete ui; }

// 1. 多播接收,对点发送
void Widget::readPendingDatagrams()
{
    auto udp = (QUdpSocket*)sender();
    while (udp->hasPendingDatagrams()) {
        QNetworkDatagram datagram = udp->receiveDatagram();
        qout << "receive msg" << datagram.data();
        qout << datagram.senderAddress() << datagram.senderPort();
        QString msg = "tcp://192.168.101.121:9999";
        udp->writeDatagram(
            msg.toUtf8(),
            datagram.senderAddress(),
            datagram.senderPort());
    }
}

你可能感兴趣的:(#,Qt,案例,QUdp)