qt之udp通信

菜头大大 菜头大大     2022-10-04     436

关键词:

前言:前一篇讲了TCP通信,这篇来看看UDP通信。

这里说明一下,UDP通信中分为三种通信分别为单播、组播和广播,下面将一一为大家介绍。

同样的我们都需要在工程文件中添加network

QT       += core gui network

进行UDP通信需要用到的头文件

#include <QUdpSocket>

这里我们把UDP通信分为两个部分写,一个是发送端,另一个是接收端,而发送端中又分为单播、组播和广播三种形式,下面我们先来看看写发送端的代码程序的步骤:

发送端Udpsend的代码:

1、单播

   (1)创建套接字    

QUdpSocket mSocket;
mSocket = new QUdpSocket();

     (2)发送数据到指定的地址和端口号 

mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("192.168.137.1"),6677);
参数:ui->textEdit->toPlainText().toUtf8 要发送的消息
QHostAddress("192.168.137.1") 接收端的ip地址
6677 端口号,要和接收端的一致

 

2、组播,组播和单播的步骤是一样的,只有ip地址处有区别

组播ip地址范围:224.0.0.0-239.255.255.255
例子:mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("224.0.0.100"),6677);

 

3、广播,广播也只有ip地址和单播有区别

广播地址ip:QHostAddress::Broadcast
例子:mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress::Broadcast,6677);

好了,单播、组播和广播的区别应该都了解了,那么我们就来看发送端(udpsend.cpp)的具体代码:

 1 #include "udpsend.h"
 2 #include "ui_udpsend.h"
 3 
 4  UdpSend:: UdpSend(QWidget *parent) :
 5     QMainWindow(parent),
 6     ui(new Ui:: UdpSend)
 7 {
 8     ui->setupUi(this);
 9 
10     //初始化创建QUdpSocket对象
11     mSocket = new QUdpSocket();
12 }
13 
14  UdpSend::~ UdpSend()
15 {
16     delete ui;
17 }
18 
19 void UdpSend::on_sendBt_clicked()
20 {
21     //单播
22    // qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("192.168.137.1"),6677);
23 
24 
25     //组播ip地址范围:224.0.0.0-239.255.255.255
26     //qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress("224.0.0.100"),6677);
27 
28     //广播
29     qint64 len = mSocket->writeDatagram(ui->textEdit->toPlainText().toUtf8(),QHostAddress::Broadcast,6677);
30 
31 
32 }

发送端的界面文件我做的很简单,我只做了发送消息框:

 

看完发送端的代码,我们继续来看接收端的代码(Udprecv)

接收端不管是单播、或者组播还是广播代码都是一样的,下面是写接收端代码的步骤:

1、创建套接字

QUdpSocket mSocket;
mSocket = new QUdpSocket();

2、绑定地址和端口号

mSocket->bind(QHostAddress::AnyIPv4,6677);
参数:AnyIPv4  IPv4
     6677  端口号,要和发送端的一致

3、等待数据的到来,利用readyRread()

connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data()));

4、读数据

readDatagram(char * data, qint64 maxSize, QHostAddress * address = 0, quint16 * port = 0)
 参数:
      data:数据
      maxSize:数据的大小
      address:QHostAddress类型的地址
      port:端口号

例子:
void UdpRecv::read_data()
{
    QByteArray array;
    QHostAddress address;
    quint16 port;
    array.resize(mSocket->bytesAvailable());//根据可读数据来设置空间大小
    mSocket->readDatagram(array.data(),array.size(),&address,&port); //读取数据
    ui->listWidget->addItem(array);//显示数据
   //发送反馈数据

}

如果是组播的话还涉及到加入组播和退出组播

加入到组播组  joinMulticastGroup
            例子:mSocket->joinMulticastGroup(QHostAddress("224.0.0.100"));
退出组播组 leaveMulticastGroup 例子: mSocket
->leaveMulticastGroup(QHostAddress("224.0.0.100"));

 

来看看接收端(Udprecv.cpp)具体实现的代码

 1 #include "udprecv.h"
 2 #include "ui_udprecv.h"
 3 
 4 UdpRecv::UdpRecv(QWidget *parent) :
 5     QMainWindow(parent),
 6     ui(new Ui::UdpRecv)
 7 {
 8     ui->setupUi(this);
 9 
10     //创建对象 初始化
11     mSocket = new QUdpSocket();
12 
13     //绑定
14     mSocket->bind(QHostAddress::AnyIPv4,6677);
15     //关联读数据信号readyread
16     connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data()));
17 
18 }
19 
20 UdpRecv::~UdpRecv()
21 {
22     delete ui;
23 }
24 
25 void UdpRecv::read_data()
26 {
27     QByteArray array;
28     QHostAddress address;
29     quint16 port;
30     array.resize(mSocket->bytesAvailable());//根据可读数据来设置空间大小
31     mSocket->readDatagram(array.data(),array.size(),&address,&port); //读取数据
32     ui->listWidget->addItem(array);//显示数据
33    //发送反馈数据
34 
35 }
36 
37 void UdpRecv::on_checkBox_clicked(bool checked)
38 {
39     if(checked)
40     {
41         //加入组播
42         mSocket->joinMulticastGroup(QHostAddress("224.0.0.100"));
43     }
44 
45     else
46     {
47         //退出组播
48         mSocket->leaveMulticastGroup(QHostAddress("224.0.0.100"));
49 
50     }
51 
52 }

接收端的界面文件我只加了显示接收到的信息和选择是否加入组播的选择按钮

 

这是发送端和接收分开来写的,此外我也实现了一下发送端和接收端写到同一个文件中

头文件qudpapp.h中的代码

 1 #ifndef QUDPAPP_H
 2 #define QUDPAPP_H
 3 
 4 #include <QWidget>
 5 #include <QUdpSocket>
 6 namespace Ui {
 7 class QUdpApp;
 8 }
 9 
10 class QUdpApp : public QWidget
11 {
12     Q_OBJECT
13 
14 public:
15     explicit QUdpApp(QWidget *parent = 0);
16     ~QUdpApp();
17 
18 private slots:
19     void on_sendSigRb_clicked(); //单播旋转轴
20     void on_sendMulRb_clicked();  //组播选择
21     void on_sendBroadRb_clicked(); //广播选择
22     void on_sendBt_clicked(); //发送按钮
23 
24 //===========================================
25     void on_recvCb_clicked(bool checked);  //选择接收
26     void on_recvJoinMulBt_clicked();  //加入组播
27     void on_recvLeaveMulBt_clicked(); //退出组播
28 
29     void on_sendMesEdit_cursorPositionChanged();//检测消息框是否有数据
30     void read_data();
31 
32 private:
33     Ui::QUdpApp *ui;
34     QUdpSocket *mSocket;
35     QHostAddress sendaddrees;
36     QString sendPort;
37 
38 };
39 
40 #endif // QUDPAPP_H
View Code

源文件qudpapp.cpp中的代码

  1 #include "qudpapp.h"
  2 #include "ui_qudpapp.h"
  3 #include <QMessageBox>
  4 QUdpApp::QUdpApp(QWidget *parent) :
  5     QWidget(parent),
  6     ui(new Ui::QUdpApp)
  7 {
  8     ui->setupUi(this);
  9     mSocket = new QUdpSocket();//创建套接字
 10     ui->sendBt->setEnabled(false);
 11 }
 12 
 13 QUdpApp::~QUdpApp()
 14 {
 15     delete ui;
 16 }
 17 
 18 
 19 //==========================发送端====================
 20 //单播选择
 21 void QUdpApp::on_sendSigRb_clicked()
 22 {
 23     if(ui->sendPortEdit->text().isEmpty() || ui->sendSigAddrEdit->text().isEmpty())
 24     {
 25         QMessageBox::warning(this,"提示","请输入单播ip和端口号");
 26         //ui->sendSigRb->setChecked(false);
 27         return;
 28     }
 29     sendaddrees.setAddress( ui->sendSigAddrEdit->text());
 30     sendPort  = ui->sendPortEdit->text();
 31 
 32 }
 33 
 34 //组播选择
 35 void QUdpApp::on_sendMulRb_clicked()
 36 {
 37     if(ui->sendPortEdit->text().isEmpty() || ui->sendMulAddrEdit->text().isEmpty())
 38     {
 39         QMessageBox::warning(this,"提示","请输入组播ip和端口号");
 40         //ui->sendSigRb->setChecked(false);
 41         return;
 42     }
 43    sendaddrees.setAddress( ui->sendMulAddrEdit->text());
 44    sendPort  = ui->sendPortEdit->text();
 45 
 46 }
 47 
 48 //广播选择
 49 void QUdpApp::on_sendBroadRb_clicked()
 50 {
 51     if(ui->sendPortEdit->text().isEmpty() || ui->sendBroadAddrEdit->text().isEmpty())
 52     {
 53         QMessageBox::warning(this,"提示","请输入广播ip和端口号");
 54         //ui->sendSigRb->setChecked(false);
 55         return;
 56     }
 57     sendaddrees.setAddress( ui->sendBroadAddrEdit->text());
 58     sendPort  = ui->sendPortEdit->text();
 59 
 60 }
 61 
 62 //发送按钮
 63 void QUdpApp::on_sendBt_clicked()
 64 {
 65     mSocket->writeDatagram(ui->sendMesEdit->toPlainText().toUtf8(),sendaddrees,sendPort.toInt());
 66 
 67 }
 68 
 69 //检测发送消息对话框中是否有消息
 70 void QUdpApp::on_sendMesEdit_cursorPositionChanged()
 71 {
 72     if(ui->sendMesEdit->toPlainText().isEmpty())
 73     {
 74         ui->sendBt->setEnabled(false);
 75     }
 76     else
 77     {
 78         ui->sendBt->setEnabled(true);
 79     }
 80 
 81 }
 82 
 83 //==========================发送端====================
 84 
 85 
 86 //==========================接收端=====================
 87 
 88 //选择接收
 89 void QUdpApp::on_recvCb_clicked(bool checked)
 90 {
 91     if(ui->recvPortEdit->text().isEmpty())
 92     {
 93         QMessageBox::warning(this,"提示","请输入端口号");
 94         ui->recvCb->setChecked(false);
 95         return;
 96     }
 97     if(checked)
 98     {
 99         mSocket->bind(QHostAddress::AnyIPv4,ui->recvPortEdit->text().toInt());
100         connect(mSocket,SIGNAL(readyRead()),this,SLOT(read_data()));
101         ui->recvPortEdit->setEnabled(false);
102     }
103     else
104     {
105         mSocket->close();
106         ui->recvPortEdit->setEnabled(true);
107     }
108 }
109 
110 //加入组播
111 void QUdpApp::on_recvJoinMulBt_clicked()
112 {
113     if(ui->recvMulAddrEdit->text().isEmpty())
114     {
115         QMessageBox::warning(this,"提示","请输入组播ip");
116         return;
117     }
118     if(mSocket->joinMulticastGroup(QHostAddress(ui->recvMulAddrEdit->text()))) //加入组播
119     {
120         ui->recvMulAddr->addItem(ui->recvMulAddrEdit->text());
121     }
122     else
123     {
124         QMessageBox::warning(this,"提示","加入组播失败,请修改ip后继续加入");
125         //return;
126     }
127 
128 }
129 
130 //退出组播
131 void QUdpApp::on_recvLeaveMulBt_clicked()
132 {
133     mSocket->leaveMulticastGroup(QHostAddress(ui->recvMulAddr->currentIndex()));//退出组播地址列表当前的组播
134     ui->recvMulAddr->removeItem(ui->recvMulAddr->currentIndex()); //删除组播地址列表中当前的组播地址
135 }
136 
137 void QUdpApp::read_data()
138 {
139     QByteArray array;
140     array.resize(mSocket->bytesAvailable()); //将接收数据的array设置成为要接收数据的大小
141     QHostAddress recvaddress;
142     quint16 port;
143     mSocket->readDatagram(array.data(),array.size(),&recvaddress,&port); //读取数据
144     ui->recvList->addItem(array);
145 
146 }
147 
148 //==========================接收端=====================
View Code

界面文件qudpapp.ui

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <ui version="4.0">
  3  <class>QUdpApp</class>
  4  <widget class="QWidget" name="QUdpApp">
  5   <property name="geometry">
  6    <rect>
  7     <x>0</x>
  8     <y>0</y>
  9     <width>637</width>
 10     <height>561</height>
 11    </rect>
 12   </property>
 13   <property name="sizePolicy">
 14    <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
 15     <horstretch>0</horstretch>
 16     <verstretch>0</verstretch>
 17    </sizepolicy>
 18   </property>
 19   <property name="windowTitle">
 20    <string>QUdpApp</string>
 21   </property>
 22   <widget class="QWidget" name="layoutWidget">
 23    <property name="geometry">
 24     <rect>
 25      <x>9</x>
 26      <y>9</y>
 27      <width>394</width>
 28      <height>463</height>
 29     </rect>
 30    </property>
 31    <layout class="QVBoxLayout" name="verticalLayout_6">
 32     <item>
 33      <layout class="QHBoxLayout" name="horizontalLayout_9">
 34       <item>
 35        <widget class="QGroupBox" name="groupBox">
 36         <property name="sizePolicy">
 37          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
 38           <horstretch>0</horstretch>
 39           <verstretch>0</verstretch>
 40          </sizepolicy>
 41         </property>
 42         <property name="title">
 43          <string>发送端</string>
 44         </property>
 45         <layout class="QVBoxLayout" name="verticalLayout_3">
 46          <property name="spacing">
 47           <number>0</number>
 48          </property>
 49          <property name="leftMargin">
 50           <number>0</number>
 51          </property>
 52          <property name="topMargin">
 53           <number>0</number>
 54          </property>
 55          <property name="rightMargin">
 56           <number>0</number>
 57          </property>
 58          <property name="bottomMargin">
 59           <number>0</number>
 60          </property>
 61          <item>
 62           <layout class="QVBoxLayout" name="verticalLayout_2">
 63            <item>
 64             <layout class="QHBoxLayout" name="horizontalLayout">
 65              <property name="spacing">
 66               <number>0</number>
 67              </property>
 68              <item>
 69               <widget class="QLabel" name="label">
 70                <property name="text">
 71                 <string>端 口 号</string>
 72                </property>
 73               </widget>
 74              </item>
 75              <item>
 76               <widget class="QLineEdit" name="sendPortEdit">
 77                <property name="sizePolicy">
 78                 <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
 79                  <horstretch>0</horstretch>
 80                  <verstretch>0</verstretch>
 81                 </sizepolicy>
 82                </property>
 83                <property name="placeholderText">
 84                 <string>请输入端口号</string>
 85                </property>
 86               </widget>
 87              </item>
 88             </layout>
 89            </item>
 90            <item>
 91             <layout class="QHBoxLayout" name="horizontalLayout_2">
 92              <property name="

qt5之udp通信(代码片段)

UDP通信的优点UDP无连接通信可以探测附近的设备减轻服务端的压力UDP步骤服务端定义一个套接字s定义文件描述符定义缓冲字符串申请一个套接字作用在文件描述符上参数一:协议->IPv4/IPv6PF_INET/PF_INET6参数二:套接字类型->UDP... 查看详情

qt学习笔记(13)qt下的udp通信

一、UDP通信  UDP通信没有明确的服务器端和客户端之分  TCP通信像是打电话(必须要接通才能通信),UDP通信像是写信(不管能不能收到都发送出去)  首先需要QUdpSOcket套接字,然后绑定bind()端口号和ip  如果对方发送... 查看详情

qt网络编程之搭建udp通信单播组播广播(代码片段)

...于项目的环境实在局域网内进行传输,所以采用了UDP通信。为此记录一下。UDP概念UDP(用户数据报协议)是一个简单的面向数据报的传输层协议。提供的是非面向连接的、不可靠的数据流传输。UDP不提供可靠性,... 查看详情

qt之udp通信(代码片段)

...一两个数据包,也不会对接收结果产生太大影响。UDP通信示意图如下:UDP消息传送有三种模式,分别是单播、广播和组播三种模式。①单播(unicast):单播用于两个主机之间的端对端通信,需要知道对... 查看详情

qt在windows下的udp通信(最简单)

qt编程:windows下的udp通信 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境:主机:win7开发环境:qt 功能:用udp进行收发通信 界面: 源代码:LssHost.pro: [cpp] viewplain copy #------------ 查看详情

qt下udp套接字通信——qudpsocket简单使用(代码片段)

QT下UDP套接字通信——QUdpSocketQUdpSocket类提供一个UDP套接字。UDP(用户数据报协议)是一种轻量级、不可靠、面向数据报、无连接的协议。它可以在可靠性不重要的情况下使用。QUdpSocket是QAbstractSocket的一个子类,允许您发送和接... 查看详情

qt-udp通信(代码片段)

...连接,只负责调用接收函数,等待客户端连接的到达。udp通信模型如下: (1)服务器端1)创建套接字;2)绑定套接字;3)接收或发送数据;4)关闭连接。(2)客户端 查看详情

python中的端口协议之基于udp协议的通信传输(代码片段)

UDP协议:  1、python中基于udp协议的客户端与服务端通信简单过程实现  2、udp协议的一些特点(与tcp协议的比较)-------------------------------------------------------------------------------------------------------------------------------------一、 查看详情

qt网络编程udp下c/s架构广播通信

QT有封装好的UDP协议的类,QUdpSocket,里面有我们想要的函数接口。感兴趣的话,可以看看。先搞服务端吧,写一个子类,继承QDialog类,起名为UdpServer类。头文件要引用我们上边说的QUdpSocket这个类,还有我们想要的布局的类。1#if... 查看详情

qt基础之二十:进程间通信

目录一.常用Qt进程间通信方式二.管道(QLocalServer、QLocalSocket)1.QLocalServer2.QLocalSocket3.一个例子 查看详情

网络编程之udp编程

UDP编程中,如果要完成通信,通信双方必须要创建DatagramSocket,通过DatagramSocket完成通信。 数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器 UDP步骤:[1]创建一个DatagramSo... 查看详情

qt的udp通信编程问题

...简单的对话程序,实现了类似QQ的两个对话框程序的文字通信,采用的是Qudpsocket。其中有两句涉及到IP地址:hostaddr1=newQHostAddress("1.1.1.1");//不透露信息我随便写的IPboolconn=udpSocket->bind(*hostaddr1,Port1);//IP是通过百度查的我... 查看详情

专题七.网络编程之套接字sockettcp和udp通信实例

...容。内容包括:服务器和客户端架构、套接字Socket、TCPUDP通信实例和常见笔试考题。https://www.cnblogs.com/alex3714/articles/5227251.html1.Socket语法及相关2.SocketServer实现多并发 一.服务器和客户端架构二.套接字Socket三.TCP通信实例四.UDP通... 查看详情

[osg][osgearth]基于qt代码实现:tcp|udp与飞行模拟软件jsbsim的通信,现实模型飞行!

废话没有,上关键代码头文件#include<QUdpSocket>#include<qtcpsocket.h>#ifndefvrUDP#definevrUDP#definePLANE_DATA_NUM30structPlanePoseStruct{doublelon;doublelat;doubleheight;doubleheading;doublepitch;doubl 查看详情

java之udp

...向指定的ip地址发数据,数据就发送到了指定的电脑。UDP通信只是一种通信方式而已,其特点就不多说。有了ip地址数据就能发送到指定的电脑了,但是呢!我把数据发送到电脑了,电脑中的哪个程序接收呢。不知道亲们知不知... 查看详情

qt基础之二十一:qtro(qtremoteobject)实现进程间通信

这里将QtRO单独从上一篇Qt基础之二十:进程间通信拎出来,因为它是Qt5.9以后新加入的模块,专门用于进程间通信。其使用步骤有点类似之前介绍过的RPC(RemoteProcedureCall)框架:gRPC和thrift,关于这两个框架详见Qt中调用thrift和Qt... 查看详情

java之udp编程

...向指定的ip地址发数据,数据就发送到了指定的电脑。UDP通信只是一种通信方式而已,其特点就不多说。有了ip地址数据就能发送到指定的电脑了,但是呢!我把数据发送到电脑了,电脑中的哪个程序接收呢。不知道亲们知不知... 查看详情

qt串口通信开发之qserialport模块(代码片段)

Qt串口通信基础及名词说明串口通信(SerialCommunications)的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根... 查看详情