Qt UDP

UDP是一种是一种轻量级、不可靠、面向数据报的无连接协议。当可靠性不重要时,可以使用它。

QUdpSocket 是 QAbstractSocket 的一个子类,所以拥有QAbstractSocket的各种方法,允许您发送和接收 UDP 数据报。

QAbstractSocket的各种函数已经在上一篇文章Qt TCP中列出,这里就不列举了。 

QUdpSocket的函数:

writeDatagram()

将数据报数据报发送到主机地址主机端口端口。

如果成功,该函数返回发送的字节数,如果遇到错误,则返回 -1。

一般发送小于512字节的数据报。

这种方法可能会掉包,所以一般使用write()发送数据报

readDatagram()

接收数据报,需要指定接收大小,成功时返回数据报的大小;否则返回 -1。

一般会先使用pendingDatagramSize()来确定数据报大小,否则多余部分将丢失。

receiveDatagram()接收数据报,并在QNetworkDatagram对象中返回该数据报,以及发送方的主机地址和端口,如果 maxSize 太小,则数据报的其余部分将丢失。如果 maxSize 为 0,则将丢弃数据报。如果 maxSize 为 -1(默认值),此函数将尝试读取整个数据报(Qt 5.8引入)
pendingDatagramSize()返回第一个挂起的UDP数据报的大小,如果没有可用的数据报,此函数返回 -1
hasPendingDatagrams()判断是否有等待的数据报
joinMulticastGroup()在操作系统选择的默认接口上加入由组地址指定的多播组,套接字必须处于连接状态
leaveMulticastGroup()将指定的多播组保留在操作系统中
multicastInterface()返回多播数据报的传出接口的接口
setMulticastInterface()设置多播数据报的接口

注意: 收到 readyRead() 信号时,应读取传入的数据报,否则不会为下一个数据报发出此信号。

UDP的构建方法:

UDP没有分客户端和服务器端,而是直接使用接收端和发送端,直接使用QUdpSocket。

  1. 创建一个QUdpSocket
  2. 使用bind()函数指定IP和端口号(接收时)
  3. 使用writeDatagram()发送数据报(需要绑定IP,和端口号)
  4. 使用readDatagram()接收数据报

bind函数:

bind(const QHostAddress & address,quint 16 port=0,QAbstractSocket::BindMode

mode=DefaultForPlatfrom)

该函数可以指定IP,端口号,绑定模式

bind(quint 16 port=0,QAbstractSocket::BindModemode=DefaultForPlatfrom)

该函数的一个重载,可以不指定IP

QAbstractSocket::BindMode

QAbstractSocket::ShareAddress允许其他服务绑定到同一地址和端口。
QAbstractSocket::DontShareAddress以独占方式绑定地址和端口,不允许重新绑定其他服务。
QAbstractSocket::ReuseAddressHint向 QAbstractSocket提供提示,即使地址和端口已由另一个套接字绑定,它也应尝试重新绑定服务。
QAbstractSocket::DefaultForPlatform当前平台的默认选项。在Unix和macOS上,这相当于(DontShareAddress + ReuseAddressHint),而在Windows上,它相当于ShareAddress。

 创建一个可接收可发送的UDP传输:

1.在pro文件中添加

QT +=network

2.ui界面中添加以下控件:

 3. .h文件中添加以下代码

#ifndef SOCKET_H
#define SOCKET_H

#include <QWidget>
class QUdpSocket;
QT_BEGIN_NAMESPACE
namespace Ui { class socket; }
QT_END_NAMESPACE

class socket : public QWidget
{
    Q_OBJECT

public:
    socket(QWidget *parent = nullptr);
    ~socket();

private slots:
    void on_pushButton_clicked();//这两个是ui界面中转到槽生成的
    void on_pushButton_2_clicked();

private:
    Ui::socket *ui;
    QUdpSocket * sk;//一个QUdpSocket对象
};
#endif // SOCKET_H

4.  .cpp文件内容

#include "ui_socket.h"
#include<QUdpSocket>
#include<QMessageBox>
socket::socket(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::socket)
{
    ui->setupUi(this);
    sk=new QUdpSocket(this);
    connect(sk,&QUdpSocket::readyRead,[=]()//如有新的数据报
    {
        while(sk->hasPendingDatagrams())//判断是否有可获取的数据报
        {
            QByteArray bta;//接收数据
            bta.resize(sk->pendingDatagramSize());//重置大小
            sk->readDatagram(bta.data(),bta.size());//获取数据
            ui->textEdit->append(QString("陌生人:%1").arg(bta.data()));//放在textEdit中显示
        }
    });
}

socket::~socket()
{
    delete ui;
}

void socket::on_pushButton_clicked()//发送数据
{
    QByteArray bta=ui->lineEdit2->text().toUtf8();//获取内容
    //发送数据,内容,大小,IP,端口号   QHostAddress::Broadcast(广播地址)255.255.255.255
    sk->writeDatagram(bta,bta.size(),QHostAddress::Broadcast,ui->lineEdit1->text().toInt());
    ui->textEdit->append(QString("自己:%1").arg(ui->lineEdit2->text()));
}

void socket::on_pushButton_2_clicked()//绑定接收端口
{
    sk->bind(ui->lineEdit3->text().toInt(),QUdpSocket::ShareAddress);//绑定端口
}

然后再创建一个项目,使用一摸一样的代码:

分别运行这两个项目:

点击该按键,可以选择项目运行。 

运行演示为:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值