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协议下收发文件,

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

相关推荐
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner2 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz7 天前
QML Hello World 入门示例
qt
xcyxiner10 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner11 天前
DicomViewer (添加模型类)3
qt
xcyxiner12 天前
DicomViewer (目录调整) 2
qt
xcyxiner12 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能14 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G14 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt