Qt网络编程之搭建Udp通信【单播、组播、广播】

简介: Qt网络编程之搭建Udp通信【单播、组播、广播】

UDP概念

UDP(用户数据报协议)是一个简单的面向数据报的传输层协议。提供的是非面向连接的、不可靠的数据流传输。UDP不提供可靠性,也不提供报文到达确认、排序以及流量控制等功能。它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。因此报文可能会丢失、重复以及乱序等。但由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。


UDP传输方式

UDP有单播、广播、组播

只有UDP有广播和多播, TCP只能进行点对点的单播, 多播的重点是高效的把同一个包尽可能多的发送到不同的,甚至可能是未知的设备。但是TCP连接是一对一明确的,只能单播。


文中涉及到所有的代码下载地址

代码下载。这里有文章中所有的代码。如果没有积分可以私聊我发你。

单播

服务端(发送者)

服务器端不需要绑定。只需要在发送时指定对方IP以及端口即可。


m_sender->writeDatagram(dataGram.data(),// 发送内容
                        dataGram.size(),// 发送长度
                        QHostAddress("192.168.0.108"),  // 对方IP
                        6666);//对方端口


客户端(接收者)

客户端需要提前将本地IP和对应的端口进行绑定。然后关联readyRead信号。进行对应的实时读取。

下面这段代码是提前进行绑定和对应的信号槽关联

    groupAddress = QHostAddress("192.168.0.112");     // 本地地址
    int port1 = 6666;                         // 本地端口
    bool ret = m_receiver->bind(groupAddress,port1,QUdpSocket::ShareAddress);
    if(ret == false)
    {
        QMessageBox::warning(this,"error", "绑定失败");
    }
    //当接收端接收到数据时,就会发送readRead信号
    connect(m_receiver,&QUdpSocket::readyRead,this,&ReceiverWidget::processData);


下面这段代码是槽函数的一个实时读取并显示在标签上。

void ReceiverWidget::processData()
{
    QString strData;
    //有未处理的数据报
    while(m_receiver->hasPendingDatagrams())
    {
        QByteArray dataGram;
        //读取的数据报大小
        dataGram.resize(m_receiver->pendingDatagramSize());
        m_receiver->readDatagram(dataGram.data(),dataGram.size());
        ui->textBrowser->insertPlainText(dataGram);   //将接收到的数据显示到标签上
        ui->textBrowser->insertPlainText("\n");   //将接收到的数据显示到标签上
    }
}


效果图


组播

组播相当于是在广播的基础上在加入组播。

服务端(发送者)

服务器端不需要绑定。只需要在发送时指定对方IP以及端口即可。

    m_sender=new QUdpSocket(this);
    QByteArray dataGram= ui->lineEdit->text().toUtf8();
    QHostAddress appaddr;
    m_sender->writeDatagram(dataGram.data(),
                            dataGram.size(),
                            QHostAddress("224.0.0.0"),// 组播地址
                            7755);


客户端(接收者)

客户端需要对应的端口进行绑定。并加入到组播地址中,然后关联readyRead信号。进行对应的实时读取。

下面这段代码是提前进行绑定、加入组并关联信号和槽

    groupAddress = QHostAddress("224.0.0.0");     // 组播地址
    port = 7755;
    m_receiver = new QUdpSocket(this);
    bool aa = m_receiver->bind(QHostAddress::AnyIPv4, port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
    if(false == aa)
    {
        qDebug() << "绑定失败!";
    }
    // 加入组播
    bool cc = m_receiver->joinMulticastGroup(groupAddress);
    if(false == cc)
    {
        qDebug() << "加入组播失败!";
    }
    //当接收端接收到数据时,就会发送readRead信号
    connect(m_receiver, &QUdpSocket::readyRead, this, &ReceiverWidget::processData);


下面这段代码是槽函数的一个实时读取并显示在标签上。

void ReceiverWidget::processData()
{
    QString strData;
    //有未处理的数据报
    while(m_receiver->hasPendingDatagrams())
    {
        QByteArray dataGram;
        //读取的数据报大小
        dataGram.resize(m_receiver->pendingDatagramSize());
        m_receiver->readDatagram(dataGram.data(),dataGram.size());
        ui->textBrowser->insertPlainText(dataGram);   //将接收到的数据显示到标签上
        ui->textBrowser->insertPlainText("\n");   //将接收到的数据显示到标签上
    }
}


效果图

广播

广播只需要绑定端口即可。

服务器(发送者)

不需要绑定。发送时仅确定端口即可。

QByteArray dataGram= ui->lineEdit->text().toUtf8();
m_sender->writeDatagram(dataGram.data(),
                            dataGram.size(),
                            QHostAddress::Broadcast,
                            7755);


客户端(接收者)

需要绑定所有的Ip地址(AnyIPv4)以及对应的端口。然后关联readyRead信号。进行对应的实时读取。

下面这段代码是提前进行绑定和对应的信号槽关联。

下面这段代码是提前进行绑定和对应的信号槽关联

    port = 7755;
    m_receiver = new QUdpSocket(this);
    bool aa = m_receiver->bind(QHostAddress::AnyIPv4, port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
    if(false == aa)
    {
        qDebug() << "绑定失败!";
    }
    //当接收端接收到数据时,就会发送readRead信号
    connect(m_receiver, &QUdpSocket::readyRead, this, &ReceiverWidget::processData);


下面这段代码是槽函数的一个实时读取并显示在标签上。

void ReceiverWidget::processData()
{
    QString strData;
    //有未处理的数据报
    while(m_receiver->hasPendingDatagrams())
    {
        QByteArray dataGram;
        //读取的数据报大小
        dataGram.resize(m_receiver->pendingDatagramSize());
        m_receiver->readDatagram(dataGram.data(),dataGram.size());
        ui->textBrowser->insertPlainText(dataGram);   //将接收到的数据显示到标签上
        ui->textBrowser->insertPlainText("\n");   //将接收到的数据显示到标签上
    }
}


效果图

目录
相关文章
|
4月前
|
Web App开发 缓存 网络协议
不为人知的网络编程(十八):UDP比TCP高效?还真不一定!
熟悉网络编程的(尤其搞实时音视频聊天技术的)同学们都有个约定俗成的主观论调,一提起UDP和TCP,马上想到的是UDP没有TCP可靠,但UDP肯定比TCP高效。说到UDP比TCP高效,理由是什么呢?事实真是这样吗?跟着本文咱们一探究竟!
117 10
|
4月前
|
网络协议 Linux 网络性能优化
Linux C/C++之TCP / UDP通信
这篇文章详细介绍了Linux下C/C++语言实现TCP和UDP通信的方法,包括网络基础、通信模型、编程示例以及TCP和UDP的优缺点比较。
94 0
Linux C/C++之TCP / UDP通信
|
5月前
|
C语言 C++ Windows
QT多插件通信框架CTK编译记录
本文记录了编译QT多插件通信框架CTK的过程,包括编译结果截图、部署配置、Log4Qt编译配置、参考链接和拓展资料。文中提供了详细的编译步骤和配置文件示例,以及相关的资源链接。
126 0
QT多插件通信框架CTK编译记录
|
5月前
|
C语言
C语言 网络编程(八)并发的UDP服务端 以进程完成功能
这段代码展示了如何使用多进程处理 UDP 客户端和服务端通信。客户端通过发送登录请求与服务端建立连接,并与服务端新建的子进程进行数据交换。服务端则负责接收请求,验证登录信息,并创建子进程处理客户端的具体请求。子进程会创建一个新的套接字与客户端通信,实现数据收发功能。此方案有效利用了多进程的优势,提高了系统的并发处理能力。
|
5月前
|
C语言
C语言 网络编程(七)UDP通信创建流程
本文档详细介绍了使用 UDP 协议进行通信的过程,包括创建套接字、发送与接收消息等关键步骤。首先,通过 `socket()` 函数创建套接字,并设置相应的参数。接着,使用 `sendto()` 函数向指定地址发送数据。为了绑定地址,需要调用 `bind()` 函数。接收端则通过 `recvfrom()` 函数接收数据并获取发送方的地址信息。文档还提供了完整的代码示例,展示了如何实现 UDP 的发送端和服务端功能。
|
5月前
|
C语言
C语言 网络编程(九)并发的UDP服务端 以线程完成功能
这是一个基于UDP协议的客户端和服务端程序,其中服务端采用多线程并发处理客户端请求。客户端通过UDP向服务端发送登录请求,并根据登录结果与服务端的新子线程进行后续交互。服务端在主线程中接收客户端请求并创建新线程处理登录验证及后续通信,子线程创建新的套接字并与客户端进行数据交换。该程序展示了如何利用线程和UDP实现简单的并发服务器架构。
|
5月前
|
网络协议 视频直播 C语言
C语言 网络编程(三)UDP 协议
UDP(用户数据报协议)是一种无需建立连接的通信协议,适用于高效率的数据传输,但不保证数据的可靠性。其特点是无连接、尽力交付且面向报文,具备较高的实时性。UDP广泛应用于视频会议、实时多媒体通信、直播及DNS查询等场景,并被许多即时通讯软件和服务(如MSN/QQ/Skype、流媒体、VoIP等)采用进行实时数据传输。UDP报文由首部和数据部分组成,首部包含源端口、目的端口、长度和校验和字段。相比TCP,UDP具有更高的传输效率和更低的资源消耗。
|
6月前
|
C++
C++ Qt开发:QUdpSocket网络通信组件
QUdpSocket是Qt网络编程中一个非常有用的组件,它提供了在UDP协议下进行数据发送和接收的能力。通过简单的方法和信号,可以轻松实现基于UDP的网络通信。不过,需要注意的是,UDP协议本身不保证数据的可靠传输,因此在使用QUdpSocket时,可能需要在应用层实现一些机制来保证数据的完整性和顺序,或者选择在适用的场景下使用UDP协议。
255 2
|
7月前
|
数据安全/隐私保护 C++ 计算机视觉
Qt(C++)开发一款图片防盗用水印制作小工具
文本水印是一种常用的防盗用手段,可以将文本信息嵌入到图片、视频等文件中,用于识别和证明文件的版权归属。在数字化和网络化的时代,大量的原创作品容易被不法分子盗用或侵犯版权,因此加入文本水印成为了保护原创作品和维护知识产权的必要手段。 通常情况下,文本水印可以包含版权声明、制作者姓名、日期、网址等信息,以帮助识别文件的来源和版权归属。同时,为了增强防盗用效果,文本水印通常会采用字体、颜色、角度等多种组合方式,使得水印难以被删除或篡改,有效地降低了盗用意愿和风险。 开发人员可以使用图像处理技术和编程语言实现文本水印的功能,例如使用Qt的QPainter类进行文本绘制操作,将文本信息嵌入到图片中,
232 1
|
6月前
|
监控 C++ 容器
【qt】MDI多文档界面开发
【qt】MDI多文档界面开发
181 0