自学内容网 自学内容网

QUdp组播在多网卡工况下接收不到数据解决办法

问题描述

QUdp组播 + 多网卡偶尔出现发送成功,但是接收不到数据的问题

解决方案:

  1. 显示ip地址时显示网卡名,用于绑定网卡
    显示格式如图:
    在这里插入图片描述
    代码如下:
void MainWindow::load_local_ipv4()
{
    QString text = pExBarLocalIPv4List->currentText();

    pExBarLocalIPv4List->clear();

    QString netWorkName, item;
    QList<QNetworkInterface> list = QNetworkInterface::allInterfaces(); //获取系统里所有的网络接口
    foreach(QNetworkInterface intf, list){
        netWorkName = intf.humanReadableName();
        foreach(QNetworkAddressEntry entry, intf.addressEntries()){
            if (entry.broadcast() != QHostAddress::Null &&
                entry.ip() != QHostAddress::LocalHost &&
                entry.ip().protocol() == QAbstractSocket::IPv4Protocol)
            {
                item  = netWorkName;
                item += "\t";
                item += "  -  ";
                item += entry.ip().toString();
                pExBarLocalIPv4List->addItem(item, QVariant(entry.ip().toString()));
            }
        }
    }

    pExBarLocalIPv4List->setCurrentIndex(pExBarLocalIPv4List->findText(text));
}
  1. 绑定网卡建立连接
//! 判断是否是选中的IP和网卡
bool isSelectIntf(QNetworkInterface& intf, QHostAddress ipv4)
{
    foreach(QNetworkAddressEntry entry, intf.addressEntries()) //intf.addressEntries()返回此接口拥有的IP地址列表及其相关的网掩码和广播地址。
    {
        if (entry.ip()            == ipv4 &&
            entry.broadcast()     != QHostAddress::Null &&
            entry.ip().protocol() == QAbstractSocket::IPv4Protocol )
        {
            return true;
        }
    }
    return false;
}

void MainWindow::slot_ctl_action_link()
{
    //组播IPv4起始地址224.0.0.0
    QHostAddress targetIpv4 = QHostAddress(pExBarTargetIPv4List->currentText());
    QHostAddress localIPv4  = QHostAddress(pExBarLocalIPv4List->currentData().toString());
    QString intfName        = pExBarLocalIPv4List->currentText().split('\t').at(0);

    if(targetIpv4.isMulticast()) //组播
    {
        QNetworkInterface intf;
        //绑定监听地址和端口
        pTrdp->bind(localIPv4, NETPORT, QUdpSocket::ShareAddress);
        //0禁止本地回环
        pTrdp->setSocketOption(QAbstractSocket::MulticastLoopbackOption, 0);
        //获取系统里所有的网络接口
        foreach(intf, QNetworkInterface::allInterfaces())
        {
            //非选中IPv4所在网卡的接口直接跳过
            if(intf.humanReadableName() != intfName) continue;
            //判断是否是选中地址的网卡
            if(isSelectIntf(intf, localIPv4)) break;
        }
        //加入组播
        if(!pTrdp->joinMulticastGroup(targetIpv4, intf))
        {
            QMessageBox::warning(nullptr, "ERROR", pTrdp->errorString());            //绑定成功则加入组播,反之关闭socket
            return;
        }

    }
    else if(targetIpv4.isEqual(QHostAddress::Broadcast))
    {
        qDebug() << "这是广播地址";
    }
    else
    {
        //单播
        pTrdp->bind(NETPORT);
    }

    pSendTimer->start();

    //! 改变按钮状态
    pExBarIPv4Link->setEnabled(false);
    pExBarIPv4UnLink->setEnabled(true);
}

原文地址:https://blog.csdn.net/qq_44084616/article/details/154229832

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!