多网卡的QUdp 组播监听

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

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

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

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

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

#include <QDebug>
#include <QNetworkDatagram>
#include <QNetworkInterface>
#include <QTimer>
#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());
    }
}

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值