QUdpSocket---单播

Qt发个UDP消息,实打实得就两步:

1)创建QUdpSocket

2)发消息

就是这么滴简单,相比纯用C/C++来写,简直简化了太多。

01 搞个UDP服务

cpp 复制代码
void DialogUdpSocket::startUdpServer()
{
    server_ = new QUdpSocket(this);
    connect(server_, &QUdpSocket::readyRead, this, [this]{
        auto datagram = server_->receiveDatagram();
        ui->plainTextEdit_serv->appendPlainText(
            QString("recv ip:%1 port:%2 msg:%3")
                .arg(datagram.senderAddress().toString())
                .arg(datagram.senderPort())
                .arg(QString(datagram.data()))
        );
        //回复
        QNetworkDatagram d;
        d.setDestination(datagram.senderAddress(), datagram.senderPort());
        d.setData("收到!");
        server_->writeDatagram(d);
    });
    connect(server_, QOverload<QAbstractSocket::SocketError>::of(&QUdpSocket::error), this, [](QAbstractSocket::SocketError err){
        qDebug() << err;
    });
    bool ret = server_->bind(QHostAddress::AnyIPv4, 8888);
    ui->plainTextEdit_serv->appendPlainText(QString("端口绑定结果:%1").arg(ret?"成功":"失败"));
    ui->plainTextEdit_serv->appendPlainText(QString("本地端口:%1").arg(server_->localPort()));
}

程序一运行就调用这个函数启动UDP服务,看代码是写了这么多,关键就两步,

server_ = new QUdpSocket(this);

创建UDP

server_->bind(QHostAddress::AnyIPv4, 8888);

绑定到本地IP的8888端口上

其它都是打辅助,草丛中插眼的。

这个UDP服务主要干一件事情:

收到消息回OK:

1、连接readyRead信号,有消息过来时,这个信号就会触发。

2、receiveDatagram() 读取消息的内容,包括发送者的ip、端口信息。

3、然后回复它"收到!"就完了。

02 无连接udp

cpp 复制代码
//客户端发送
void DialogUdpSocket::on_pushButton_send_clicked()
{
    //创建
    if(client_ == nullptr)
    {
        client_ = new QUdpSocket(this);
        connect(client_, &QUdpSocket::readyRead, this, [this]{
            auto datagram = client_->receiveDatagram();
            ui->plainTextEdit_client->appendPlainText(
                QString("serv reply: %1").arg(QString(datagram.data()))
            );
        });
        connect(client_, &QUdpSocket::stateChanged, this, [](QAbstractSocket::SocketState socketState){
             qDebug() << socketState;
        });
    }
    //发送一个消息
    QString msg = ui->lineEdit_send->text();
    client_->writeDatagram(msg.toUtf8(), QHostAddress::LocalHost, 8888);
    ui->plainTextEdit_client->appendPlainText(QString("send msg: %1").arg(msg));
}

1)创建一个QUdpSocket

  1. writeDatagram 发送消息给上面的UDP服务

看下咱们做好的示例:

代码本豆故意连接stateChanged信号

看下它的打印:

就是说,

虽然我们没给客户端udp做端口绑定,

但是客户端在发消息会自动绑定一个端口。

示例中是绑定到52040端口上了,

这是系统随机给udp分配的一个可用端口。

作为一个发送客户端,

通常情况下还真就不需要显式绑定端口,

需要显式绑定的一般是服务端。

总不能让服务端的端口随机绑定吧,

那客户端在这六万个端口里可不知道,

哪个是自家的服务了。

03 有连接udp

把前面的客户端代码改改:

改动一:创建好socket后直接去连接服务端

改动二:用write发送消息

看看还能不能发送消息:

眉毛冰!

有连接的UDP,

1)显而易见的好处:

发消息时就不用再去指定目标IP和端口!

2)还有个好处是:

它能略微提升些性能!
首先需要说明的是,

UDP的连接只是虚拟的连接,

或者叫逻辑上的连接,

与服务端并无真实连接。

逻辑连接是让系统记录下通信双方,

节省系统对IP和端口的解析流程,

还能过滤掉无关数据包,减少无效数据的处理。
举个栗子:

TFTP是简单文件传输协议,

使用UDP进行传输。

所以在TFTP协议下收发文件,

用有连接的方式稳定性和效率上会更高些。

相关推荐
我是小灰灰吖3 小时前
QT在线安装器使用指南:从下载到配置完整教程
linux·qt·ubuntu
C++ 老炮儿的技术栈5 小时前
从 Qt Designer 属性编辑器的层级可以看到继承链
c语言·数据库·c++·qt·sqlite·visual studio
我是小灰灰吖7 小时前
Ubuntu 22.04 + Qt 6.9.3 应用程序打包与部署完整指南
qt·ubuntu
qq_401700419 小时前
Qt自定义信号槽详解:带参发射 vs sender()获取,两种多信号关联方案全掌握
java·数据库·qt
郝学胜-神的一滴11 小时前
Qt 高级编程 042:进度条从入门到自定义美化
开发语言·c++·qt·软件开发·用户界面
AI的探索之旅12 小时前
嵌入式视觉学习路线:Qt + OpenCV + 工业相机,从零到综合项目
qt·opencv·学习
我是小灰灰吖13 小时前
Ubuntu22.04,OpenCV 4.5.5 环境搭建
linux·qt·ubuntu
≮傷£≯√1 天前
Opencv VideoCapture
qt·opencv
雨田言炎2 天前
十、QThread多线程
linux·服务器·开发语言·前端·qt
常乐か2 天前
在 Ubuntu 24.04 中编译 Qt 5.15.2 项目完全指南
linux·qt·ubuntu