QT组播的建立和使用(绑定特定的网卡,绑定特定IP)

【QT】UDP通信QUdpSocket(单播、广播、组播) UDP是无连接、不可靠、面向数据报(datagram)的协议,可以应用于对可靠性要求不高的场合。与TCP通信不同,UDP通信无需预先建立持久的socket连接,UDP每次发送数据报都需要指定目标地址和端口。QUdpSocket以数据报传输数据,而不是以连续的数据流。发送数据报使用函数,数据报的长度一般少于512字节,每个数据报包含发送者和接收者的IP地址和端口等信息。UDP数据接收,首先要使用绑定一个端口,绑定端口后,socket的状态会变为已绑定状态“BoundState”。 阅读详情

https://blog.youkuaiyun.com/only_write_bug/article/details/159115776?spm=1011.2415.3001.5331

目录

一、组播介绍

二、组播初始化和使用

        1、创建QUdpSocket对象

        2、绑定本地端口

        3、加入组播组

        4、发送组播数据

        5、接收组播数据

        6、离开组播组

三、为什么需要指定网卡,如何绑定固定网卡

       1、如何查看自己电脑有那些网卡信息

        2、如何查找自己电脑对应IP的网卡信息以及绑定


一、组播介绍

        组播(Multicast)是一种高效的网络通信方式,它允许将数据包同时发送给一组特定的接收者,而无需为每个接收者都复制一份数据。

        组播地址:IPv4组播地址范围是 224.0.0.0 ~ 239.255.255.255(D类地址)。其中 224.0.0.0 ~ 224.0.0.255 为本地链路组播地址(如 224.0.0.1 表示所有子网主机),通常不被应用程序使用;239.0.0.0 ~ 239.255.255.255 为管理权限组播地址(私有组播地址),适合内部网络使用。

        组播组:加入同一个组播地址的所有主机形成一个组播组。发送者只需将数据发往组播地址,路由器会负责将数据复制到有接收者的链路上。

相关链接:

https://blog.youkuaiyun.com/only_write_bug/article/details/159115776?spm=1011.2415.3001.5331

二、组播初始化和使用

        1、创建QUdpSocket对象

QUdpSocket *udpSocket = new QUdpSocket(this);

        2、绑定本地端口

    // ShareAddress :允许共享地址。如前所述,允许多个套接字绑定到同一地址和端口
    // ReuseAddressHint: 提示地址重用。为套接字提供一个“提示”,告诉它即使地址和端口正被另一个套接字使用,也应尝试重新绑定。
    // ShareAddress和ReuseAddressHint通常一起使用

        这里绑定到 QHostAddress::AnyIPv4 表示监听所有网络接口上的指定端口。如果希望只监听特定网卡,可以传入该网卡的IP地址。

udpSocket->bind(QHostAddress::AnyIPv4, 12345, QUdpSocket::ShareAddress);

        这里为绑定到特定IP地址和端口,selfip为QString对象,所以需要转换为QHostAddress。selfip和port为你需要绑定的ip和端口。

if (!udpSocket->bind(QHostAddress(selfip), myport, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
        qWarning() << "Failed to bind status socket:" << m_socket->errorString();
    }

        3、加入组播组

QHostAddress multicastAddr("239.255.43.21");
udpSocket->joinMulticastGroup(multicastAddr);

        多个网卡的情况下,你已知自己需要绑定的网卡名称,可直接绑定到对应网卡。如下:

QNetworkInterface interface = QNetworkInterface::interfaceFromName("eth0");
udpSocket->joinMulticastGroup(multicastAddr, interface);

        4、发送组播数据

        发送方不需要加入组播组,只需将数据报的目的地址设为组播地址即可。发送前建议设置组播数据包的TTL(生存时间):

udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 1); // TTL=1 限制在本地子网
udpSocket->writeDatagram(datagram.data(), datagram.size(), multicastAddr, 12345);

        5、接收组播数据

        当有数据到达绑定的端口时,QUdpSocket 会发出 readyRead() 信号,在槽函数中读取:

connect(udpSocket, &QUdpSocket::readyRead, this, [=](){
    while (udpSocket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;
        udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
        // 处理数据或者定义信号将数据传到其他线程进行处理...
    }
});

        6、离开组播组

        当你的程序不再需要接收组播信息时,应该先离开组播组

udpSocket->leaveMulticastGroup(multicastAddr);

三、为什么需要指定网卡,如何绑定固定网卡

        当你调用udpSocket->bind(QHostAddress::AnyIPv4, 12345, QUdpSocket::ShareAddress);绑定任意IP信息时,如果你的电脑只有一个网卡的话问题不大,但是如果有多个网卡就会出现接收不到信息的问题,因为电脑组播在接收数据流的时候可能会切换到其他网卡接收,导致组播接收数据出现丢失,但是不会影响你的组播信息发送。

        所以在电脑有多网卡或者有虚拟环境的时候,推荐组播绑定到特定的网卡。

       1、如何查看自己电脑有那些网卡信息

        添加<QNetworkInterface>  <QNetworkDatagram>头文件之后,可调用QT的 QNetworkInterface::allInterfaces()查看目前你的电脑可用的所有网卡信息。如果你已知你的网卡信息就不需要。

QString info = "<<<<<<<<Available network interfaces>>>>>>>>";
    qDebug()<<info;
    foreach (QNetworkInterface iface, QNetworkInterface::allInterfaces()) {
        if (iface.flags() & QNetworkInterface::IsUp &&
            iface.flags() & QNetworkInterface::IsRunning &&
            !(iface.flags() & QNetworkInterface::IsLoopBack)) {
            info = "  Interface:" + iface.name()
                   + "  Human readable:" + iface.humanReadableName();
            qDebug()<<info;
            foreach (QNetworkAddressEntry entry, iface.addressEntries()) {
                if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
                    info = "    IP:" + entry.ip().toString();
                    qDebug()<<info;
                }
            }
        }
    }

        2、如何查找自己电脑对应IP的网卡信息以及绑定

        self为自身IP信息。

 QNetworkInterface   m_multicastIface;
if (!selfip.isEmpty()) 
{
        const auto interfaces = QNetworkInterface::allInterfaces();
        for (const QNetworkInterface &iface : interfaces) //遍历所有网卡信息
        {
            for (const QNetworkAddressEntry &entry : iface.addressEntries()) //遍历所有IP地址
            {
                if (entry.ip().toString() == selfip)//找到对应IP信息
                {
                    m_multicastIface = iface;
                    qDebug() << "找到匹配网卡:" << iface.humanReadableName() << "IP:" <<selfip;
                    break;
                }
            }
            if (m_multicastIface.isValid()) break;
        }
}

//加入组播组
if (m_multicastIface.isValid()) 
{
    if (m_socket->joinMulticastGroup(groupAddress, m_multicastIface)) 
    {
        qDebug() << "通过网卡" << m_multicastIface.humanReadableName() << "加入组播组成功";
        // 设置组播发送的接口(确保发送也走同一网卡) 可不设置
        udpsocket->setMulticastInterface(m_multicastIface);
     } else{
        qWarning() << "指定网卡加入组播组失败:" << udpsocket->errorString();
     }
 }

QT读取网卡列表多网卡绑定组播网卡 QT多网卡组播 阅读详情

相关推荐

Qt(三):udp组播的发送与接收

使用类创建一个UDP套接字。绑定套接字到一个本地地址和端口。可以使用bind()函数来完成。如果要在组播中发送数据,可以将套接字绑定到一个通配符地址(如)和指定的端口上。使用joinMulticastGroup()函数将套接字加入到指定的组播组中。该函数需要指定组播组的地址和接口地址。使用发送组播数据。需要指定要发送的数据、目标地址(即组播组的地址)和端口号。当套接字收到组播数据时,会发出信号。在槽函数中,可以使用readDatagram()函数。

weixin_51631044的博客 6578

64.QT-单播、广播、组播

本章主要描述QT中如何实现单播、广播、组播,大家可以直接参考qt官方例子: Broadcast Sender : 广播方式发送 Broadcast Receiver : 广播方式接收 Multicast Sender : 组播方式发送 Multicast Receive : 组播方式接收 需要用到的函数 bool QAbstractSocket::bind(const QHostAddre...

抵抗时间扭曲,坚持做一件有意义的事 2602

qt udp & 组播 & 多网卡

一、前言 以下代码实现了udp组播的接收和发送数据的功能。但是,在多网卡环境下仍然存在部分问题,但也解决了大部分问题。具体的内容在下面叙述。 二、大致步骤 QT += network .pro文件添加network #include <QUdpSocket> 导入头文件 QUdpSocket* udpSocket = new QUdpSocket; new个对象 udpSocket->setSocketOption(QAbstractSocket::MulticastLoopbackOpt

qq_44084616的博客 1万+

Qt多网卡组播解决方法:Qt环境下多网卡组播传输的完美解决方案

Qt多网卡组播解决方法:Qt环境下多网卡组播传输的完美解决方案 【下载地址】Qt多网卡组播解决方法 本开源项目提供了一套完整的Qt环境下多网卡组播问题的解决方案,包含源码和详细说明文档。通过绑定IP地址和端口、设置组播网卡、加入组播组并指定网卡等核心步骤,开发者能够轻松实现多网卡环境下的组播传输。项目特别适用于需要在复杂...

gitblog_06784的博客 511

Qt组播多网卡绑定实战:指定网卡与IP的完整方案

组播(Multicast)是介于单播与广播之间的一对多通信方式,通过组播组地址实现跨网段数据分发,在工业设备发现、服务宣告和实时数据同步等场景中应用广泛。但多网卡环境下,系统默认路由往往导致组播报文从错误网卡发出,造成接收端无法收到数据。利用Qt的QUdpSocket与QNetworkInterface,开发者可以显式绑定指定网卡和IP,通过joinMulticastGroup与setMulticastInterface控制收发路径,结合bind到具体本地地址的方式避免默认路由的干扰。这种方案尤其适合工控机

weixin_29189381的博客 203

从零构建:Qt与ONVIF协议模拟器的多网卡组播陷阱与实战避坑指南

本文深入解析了在Qt框架下开发ONVIF协议模拟器时,多网卡环境导致的组播通信陷阱与解决方案。通过剖析ONVIF组播机制,提供明确的接口绑定实践、抓包分析方法及跨平台兼容性处理,帮助开发者构建稳定的设备发现功能,规避常见的设备模拟器开发难题。

qsc901234567的博客 1103

Qt多网卡组播问题解决方法

一、概述 Qt组播实现起来比较简单,基本步骤是先绑定IP地址和端口,然后加入组播组,将网卡数据准备完成信号与一个数据接收处理的槽函数连接即可。但是如果计算机上多于两块网卡,就必须再增加两个步骤才行:使用setMulticastInterface设置组播网卡,然后加入组播的同时指定网卡joinMulticastGroup(groupAddr, lni[nIndex])。否则的话向组播地址发送数据时,对端的服务器程序就无法接收到数据。 二、运行效果图 转存失败重新上传取消 三、简要步骤 绑定IP地址和

sun_xf1的博客 8936

QUdpSocket组播TTL设置实战:从绑定IP到发送数据的完整流程

本文详细介绍了在Qt框架下使用QUdpSocket实现组播通信的完整流程,重点解析了TTL(Time To Live)设置的原理与实践技巧。从基础配置、加入组播组到正确设置TTL值,提供了完整的代码示例和最佳实践,帮助开发者高效控制组播数据包的传输范围,优化网络资源利用率。

weixin_30338481的博客 585

Qt多网卡组播解决方法

Qt多网卡组播解决方法 【下载地址】Qt多网卡组播解决方法 本开源项目提供了一套完整的Qt环境下多网卡组播问题的解决方案,包含源码和详细说明文档。通过绑定IP地址和端口、设置组播网卡、加入组播组并指定网卡等核心步骤,开发者能够轻松实现多网卡环境下的组播传输。项目特别适用于需要在复杂网络环境中使用Qt进行高效数据传输的开发...

gitblog_06773的博客 376

Qt实现UDP单播、组播和广播功能

对象会选择其中一个地址来接收数据包。这个选择通常由操作系统或网络栈决定,并且可能会受到各种因素的影响,例如网络接口的优先级、路由表等。对象绑定到本机的所有 IPv4 地址,但实际上它只能通过其中一个地址接收数据包。然而,需要注意的是,绑定到多个 IPv4 地址并不意味着可以同时从多个地址接收数据包。对象可以接收通过本机的任意一个 IPv4 地址发送到指定端口的数据包。对象绑定到本机的所有 IPv4 地址。多网口的话,要指定唯一的网卡ip,之后加入组播。对象只能通过一个 IP 地址接收数据包。

我智商开挂的博客 1万+

Qt多网卡组播收不到数据?原理分析与代码绑定解决指南

在工控上位机、网络通信与分布式系统开发中,多网卡环境下的UDP组播通信时常出现数据收不到或时通时断的故障。这通常并非代码逻辑错误,而是操作系统在IGMP报文出口选择、路由表匹配以及套接字绑定等底层环节上未能正确引导流量所致。理解组播地址与IGMP报告的工作机制,是定位问题的前提;通过枚举网卡、显式绑定本地IP、使用joinMulticastGroup指定网络接口,可以在Qt中稳定收发组播数据。此外,防火墙策略、交换机IGMP Snooping以及多socket并发等因素也会影响最终效果。掌握从路由表排查到代

weixin_31155097的博客 307

QT 关于多网卡组播

【代码】QT 关于多网卡组播。

lurenyi的专栏 2139

抖音自定义卡片链接(图文链接)

抖音自定义可以自定义标题,打开链接,和展示图片 效果 主要代码 public void sendMessage(String conversationId, Object aBaseContent) throws Exception { // C233282u5.LIZIZ.LIZ().LIZIZ(LIZ).LIZ(obtain).LIZ(hLn).LIZ((AbstractC59811HHc) new H9Q()); Object HOa = ReflectionUtil

傅恒的博客 4140

总结QUdpSocket组播数据发不出去问题

1是允许loopback模式(自发自收),0是阻止。这个阻止还是允许,不同系统又不同的解释:假如在同一台计算机上有两个应用程序,并且加入了同一个组播。这两个程序,一个允许回环,一个阻断回环,则会有如下现象:windows下,允许方不能发向阻断方,但阻断方可以发向允许方;linux下,允许方可以发向阻断方,但阻断方不能发向允许方。

houmingyang的专栏 5736

路径规划:D*Lite寻路算法详解

D*Lite详解目录

mkr67n的博客 2万+

在不同版本Python中安装PyQT5及PyQT5-Tools

在不同版本Python中安装PyQT5及PyQT5-Tools

zoomgu680的博客 2万+

Linux下QT实现UDP组播方式和Windows下的区别

3.注意之前使用QHostAddress::AnyIPv4绑定的小伙伴需要注意,检查自己发送UDP数据的时候绑定的IP是否和目标IP在同一网段,不然可能会出现,调用发送IP与目的IP不在同一网段(建议禁用自己的无线网卡和虚拟网卡,在有线网卡上配置对应的IP)。很多小伙伴,可能再实现开始可能会先绑定自身的IP,再加入组播组可能会导致收不到组播数据的情况,当你使用bind函数将套接字绑定到固定的IP地址时,该套接字只会接收目标IP为该固定IP的数据包。检查配置路由配置成功后,就可以开始调试啦!

zhouzhouyaonvli的博客 1356

NBIS单细胞教程:差异基因(五)

此文章是通过学习瑞典国家生物信息学基础设施(NBIS) 所开放的单细胞分析教程加上网上所查找的资料,自身的理解所形成的,可能会有不足之处。该部分是对不同集群之间的差异基因进行分析。参考来源:https://github.com/NBISweden/workshop-scRNAseq/blob/master/labs/seurat/seurat_05_dge.Rmd感兴趣的话可以阅读原文。

songyi10的博客 1万+

Qt 组播问题 Win10 Win11

Win10中 需要先设置组播网卡,然后在加入组,入组时还不能再指定接口。Win11 中 qt 仅需绑定指定接口的本地ip和加入组就可以了。

yyc520的专栏 635

逆变器、转换器、DCDC、继电器等器件的原理和作用

交流电变成直流电的过程:整流==》滤波==》稳压。

m0_61973119的博客 8028

抓包网络调试工具 reqable抓包教程

如果CA根证书未安装成功,网络图标是黄色,点击盾牌图标可以进入CA根证书安装界面,详细步骤请阅读。在API调试中,获取流量是第一步也是最基本的操作,这里讲解下如何使用Reqable获取流量,通俗地讲就是抓包。我们可以选择一个图片请求,双击打开详情面板,能够看到该请求的详细信息。如果系统代理未设置,网络图标是黄色,点击网络图标可以自动设置系统代理。此域名的结构树,可以查看该域名下所有请求的目录结构,点击选择可以查看该请求的详情。首先,需要启用Reqable的调试功能,点击最右上角的。打开浏览器,输入地址。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 2554

linux下UDP组播接收不到数据的说明

背景 在一个跨平台的桌面项目中,由于涉及多线程中对象的创建、销毁等,基于QT的对象绑定机制(QObject子类)来做实现时,需要相当心累的设计,才能避免跨线程的异常。由于QT的这个天然机制,在实现很多业务(非界面)模块时,都避免了基于QObject。网络模块中的UDP等功能,同样的也未基于QUdpSocket及其相关,而是包装了libuv(尽管,对桌面来说libuv也需要再折腾,但libuv作者已经明示了这个点了) 现象 基于libuv的程序示例,在windows下,可以正常工作(接收到组播数据.

smartcore 1万+

华为防火墙——本地Portal认证

配置IP地址、路由、Nat策略使得内网主机可以访问公网服务器对网段不进行认证,对网段进行portal认证。

m0_49864110的博客 3258

linux系统下多网卡UDP组播通信

执行 sendUDP从万兆网卡发送出去,下图为PC2(192.168.1.98)windows系统UDP测试工具接收到的数据。执行sendUDP从千兆网卡发出去,下图为PC2(192.168.4.29)linux系统接收到kylin发送过来的数据。执行 recvUDP接收 程序。

Matlab0224的博客 1619

【Zephyr存储专题】06_存储块设备驱动开发(Nand Flash)

本文介绍了基于Zephyr系统的NAND Flash驱动实现方案,重点阐述了Flash驱动模型的核心架构和关键API设计。

zero的博客 1802

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

上一篇: 基于I/O复用的服务器端搭建
下一篇: QNetworkInterface类介绍
西装没钱买
博客等级 码龄4年 620粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值