QT学习笔记之UDP通信

一、UDP通信

使用Qt来实现TCP和UDP通信时,虽然基本的编程概念相似,但是由于两种协议本身的特点,实现方式和使用场景会有所不同。

以下是使用Qt实现TCP和UDP通信时的一些主要区别:

1. 通信方式:

TCP:Qt中使用QTcpServerQTcpSocket两个类来实现基于TCP的通信。QTcpServer用于创建服务器端应用程序,而QTcpSocket既可以用于创建客户端。TCP是面向连接的,所以在使用QTcpSocket时,需要先调用connectToHost方法来建立连接,然后才能发送和接收数据。连接建立后,数据传输是双向的,可以同时进行发送和接收。所以在TCP通信的中我们不仅实现了TCP客户端还实现了TCP服务器。

UDPQt中使用QUdpSocket一个类来实现基于UDP的通信。UDP是无连接的,使用QUdpSocket时可以直接发送数据,不需要建立连接。发送和接收数据是独立的操作,发送数据使用write方法,接收数据则是通过信号readyRead来处理。所以UDP通信实现起来更加容易,UDP不分客户端和服务器,只需要创建一个工程即可。

2. 数据流与数据报:

TCP:QTcpSocket处理的是面向流的数据,数据在发送和接收时是以连续的字节流形式进行的,没有明确的数据边界。

UDP:QUdpSocket处理的是数据报,每个发送和接收的数据单元都是独立的,具有明确的边界。这使得UDP在处理某些需要独立数据包的应用时更为方便。

3. 可靠性与效率:

TCP:使用QTcpSocket时,Qt会自动处理数据的可靠性,包括数据的顺序、完整性和重传机制。这使得TCP通信更加稳定,但也意味着会有更多的开销。

UDP:使用QUdpSocket时,开发者需要自己处理数据的顺序和完整性。UDP通信效率更高,但可能会有丢包的情况发生。

4. 错误处理:

TCP:QTcpSocket提供了一些错误信号,如disconnected、error等,可以用来处理连接断开或通信错误的情况。

UDP:QUdpSocket同样提供了error信号,但由于UDP的特性,错误处理通常更加简单,主要是处理无法发送或接收数据的情况。

示例代码:

TCP 示例:

1. QTcpSocket *socket = new QTcpSocket(this);

2. socket->connectToHost("server.example.com", 1234);

3. connect(socket, &QTcpSocket::readyRead, this, &MyClass::onReadyRead);

4. socket->write("Hello, Server!");

UDP 示例:

1. QUdpSocket *socket = new QUdpSocket(this);

2. socket->bind(QHostAddress::Any, 1234);

3. connect(socket, &QUdpSocket::readyRead, this, &MyClass::onReadyRead);

4. socket->writeDatagram("Hello, Server!", QHostAddress("server.example.com"), 1234);

在使用Qt进行网络编程时,选择TCP还是UDP主要取决于应用的需求。如果需要可靠的数据传输和流式处理,TCP是更好的选择;如果对实时性要求较高,可以容忍一定程度的数据丢失,并且希望避免建立连接的开销,那么UDP可能更适合。Qt提供了丰富的类和方法来支持这两种协议的实现,开发者可以根据具体情况灵活选择。

二、创建UDP工程(与TCP工程步骤一致)

第一步:打开QT软件,新建工程;

第二步:选择一个模板(默认即可);

第三步:设置项目名称以及项目存储路径;

第四步:编译器选择(默认即可)

第五步:基类选择(QWidget

第六步:项目管理(默认即可)

第七步:生成工程

第八步:编译验证(Ctrl + R如图所示,创建工程成功)

三、设置UI界面

第一步:双击Forms文件下的widget.ui文件

第二步:设置UI界面

以接收框为例,步骤如下:

UI界面设置包含下面7步:

1. 接收框:Plain Text Edit控件(重命名:receiveEdit)

2. 发送框:Line Edit控件(重命名:sendEdit)

3. 接收窗口和发送窗口:Group Box控件

4. 本地端口框:Line Edit(重命名:localPort) + Label控件

5. 目标端口框:Line Edit(重命名:aimPort) + Label控件

6. 目标IP框:Line Edit(重命名:aimIp) + Label控件

7. 按钮:PushButton 控件:

打开(重命名:openBt)、关闭(重命名:closeBt)、发送(重命名:sendBt)

最后设置编译运行效果如下:

四、新类的使用(QUdpSocket Class)

步骤:帮助->索引->搜索“QUdpSocket类”

下滑可查看使用示例:

1. 在widget.h文件中,添加所用头文件:#include  <QUdpSocket>

2. 在.pro文件中,添加network;

3. 在widget.h文件中,定义指针变量,用于创建和操作UDP;

4.在widget.cpp文件中的构造函数中,使用new关键字,为指针变量分配内存,初始化指针。

五、功能实现逻辑代码编写

UDP所需要实现的功能:

①打开UDP,并绑定本地端口号;

②连接信号,接收数据,并在接收窗口显示数据;

③发送数据至指定的地址和端口;

④关闭UDP

1. 打开UDP,并绑定本地端口号

第一步:关联“打开按钮控件”信号和槽(自动关联)

 

第二步:编写代码,绑定本地端口号;

  

注释:在Qt中,调用 udpSocket->bind(ui->localPort->text().toUInt()); 这行代码的目的是将 QUdpSocket 对象绑定到由用户通过UI界面(比如一个文本输入框 QLineEdit)指定的端口上。这里的 ui 是一个指向 Ui::类名 的指针,它是一个由QtUI编译器自动生成的类,包含了你在Qt Designer中设计的用户界面的所有部件。

1. ui->localPort:这通常是一个指向 QLineEdit 或类似文本输入控件的指针,它允许用户输入数据。

2. ->text():这是对 QLineEdit 或文本输入控件的成员函数调用,用于获取用户输入的文本。

3. .toUInt():这是一个将 QString 对象(用户输入的文本)转换为 unsigned int(无符号整数)的方法。这里使用 toUInt() 是因为它期望端口号是一个非负整数,而端口号的范围是从065535

4. udpSocket->bind():这是 QUdpSocket 类的成员函数,用于将UDP套接字绑定到一个特定的端口上。绑定后,套接字就可以接收发送到该端口的UDP数据报了。

将这些组合起来,udpSocket->bind(ui->localPort->text().toUInt()); 这行代码的作用是将UDP套接字绑定到用户在 ui->localPort 控件中输入的端口号上。如果用户输入了一个有效的端口号,UDP套接字将监听该端口的入站数据报。

第三步:增加提示功能

2. 连接信号,接收数据,并在接收窗口显示数据(同理于TCP的槽函数编写,手动关联)

第一步:连接信号:connect(udpSocket, SIGNAL(readyRead()),this, SLOT(readyRead_Slot()));

第二步:在widget.h文件中定义槽函数:void readyRead _Slot()

第三步:在widget.cpp文件中编写槽函数void Widget:: readyRead_Slot()代码

注释:上述代码是在Qt应用程序中使用 QUdpSocket 来接收UDP数据报,并将接收到的数据展示在用户界面上。readyRead_Slot 函数是与 QUdpSocket readyRead 信号连接的槽函数。当 QUdpSocket 可读时,即当它接收到新的UDP数据报时,该槽函数会被调用。

1. while (udpSocket->hasPendingDatagrams()) 循环用于读取所有待处理的数据报。这是因为在某些情况下,可能同时接收到多个数据报。

2. QByteArray array; 创建一个 QByteArray 对象用于存储接收到的数据。

3. array.resize(udpSocket->pendingDatagramSize()); 调整 QByteArray 的大小以匹配即将读取的数据报的大小。

4. udpSocket->readDatagram(array.data(), array.size()); QUdpSocket 读取一个数据报到 QByteArray

5. QString buff; 创建一个 QString 对象。

6. buff = array.data(); QByteArray 转换为 QString

7. ui->receiveEdit->appendPlainText(buff); 将接收到的数据追加到用户界面的文本编辑器中。

第四步:运行程序

第五步:验证接收数据效果(与网络调试助手联调)

如上述所示,已可以正常接收调试助手发送的数据。

3. 发送数据至指定的地址和端口

第一步:关联“发送按钮控件”信号和槽(自动关联);

第二步:编写代码,将(ui->sendEdit)控件输入的数据发送给指定的地址和端口;

注释:上述代码是一个Qt槽函数 on_sendBt_clicked,它在用户点击发送按钮时被触发,用于发送UDP数据报。on_sendBt_clicked 函数处理发送UDP数据报的逻辑:

1. address.setAddress(ui->aimIp->text());:获取用户在UI组件中输入的目标IP地址,并将该地址设置为 QHostAddress 对象。

2. sendbuff = ui->sendEdit->text();:获取用户在发送文本编辑器中输入的字符串,这将作为UDP数据报的内容。

3. port = ui->aimPort->text().toUInt();:获取用户输入的目标端口号,并转换为无符号整数。

4.udpSocket->writeDatagram(sendbuff.toLocal8Bit().data(), sendbuff.length(), address, port);:将 sendbuff 转换为本地8位编码(通常是ISO 8859-1Windows-1252),然后使用 QUdpSocket writeDatagram 方法发送数据报到指定的地址和端口。

第三步:运行程序,并验证发送数据功能

4. 关闭UDP

第一步:关联“关闭按钮控件”信号和槽(自动关联);

第二步:编写代码,关闭UDP

【笔记学习自北京讯为电子嵌入式学习之QT学习篇】

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值