[Qt][Qt 网络][上]详细解说

[复制链接]
发表于 2026-10-4 14:44:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

Qt 的网络编程建立在 BSD socket 之上,Qt 把它包成了信号槽友好的类。先用 UDP 开一条路:QUdpSocket 负责收发,QNetworkDatagram 承载一个数据报。本文把核心 API、回显服务器与回显客户端三段代码讲透。

一、先加模块

要用 Qt 的网络 API,工程里必须加 network 模块(在 .pro 文件里 QT += network),否则编译期就报找不到头文件。

二、核心类与 API

主要就两个类:

  • QUdpSocket 表示一个 UDP socket:bind(const QHostAddress &, quint16) 绑定端口(对应原生 bind());receiveDatagram() 读一个 UDP 数据报(对应 recvfrom());writeDatagram(const QNetworkDatagram &) 发送(对应 sendto());readyRead() 是收到数据就绪时触发的信号,类似 IO 多路复用的通知机制。
  • QNetworkDatagram 表示一个 UDP 数据报:QNetworkDatagram(const QByteArray &, const QHostAddress &, quint16) 用数据、目标 IP、目标端口构造,多用于发送;data() 取数据;senderAddress() 与 senderPort() 取对端的 IP 与端口。

三、回显服务器

顺序很重要:先连信号槽,再绑定端口。反过来可能出现端口绑好、请求已到但槽还没连上,这个请求就漏了。

// 构造函数中
socket = new QUdpSocket(this);
connect(socket, &QUdpSocket::readyRead, this, &Widget:rocessRequest);

// 绑定端口号
if (!socket->bind(QHostAddress::Any, 2333)) {
    QMessageBox::critical(this, "服务器启动出错", socket->errorString());
    return;
}

void Widget:rocessRequest() {
    // 1. 读取请求并解析
    const QNetworkDatagram &req = socket->receiveDatagram();
    QString request = req.data();
    // 2. 根据请求计算响应
    const QString &response = Process(request);
    // 3. 把响应写回客户端
    QNetworkDatagram resp(response.toUtf8(), req.senderAddress(), req.senderPort());
    socket->writeDatagram(resp);
    // 4. 把交互信息显示到界面
    QString log = "[" + req.senderAddress().toString() + ":" +
                  QString::number(req.senderPort()) + "] req:" + request + ", resp:" + response;
    ui->listWidget->addItem(log);
}

QString Widget:rocess(const QString &request) {
    return request;   // 回显
}

四、回显客户端

// 构造函数中
socket = new QUdpSocket(this);
connect(socket, &QUdpSocket::readyRead, this, &Widget:rocessResponse);

void Widget:n_pushButton_clicked() {
    const QString &text = ui->lineEdit->text();
    QNetworkDatagram req(text.toUtf8(), QHostAddress(SERVER_IP), SERVER_PORT);
    socket->writeDatagram(req);          // 发送请求
    ui->listWidget->addItem("客户端说:" + text);
    ui->lineEdit->setText("");           // 清空输入框
}

void Widget:rocessResponse() {
    const QNetworkDatagram &resp = socket->receiveDatagram();
    ui->listWidget->addItem("服务器说:" + resp.data());
}

五、UDP 这套用在哪

UDP 不保证到达与顺序,代价换来的是低延迟,适合局域网内的状态广播、心跳上报、音视频流。要可靠传输就把这套换成 QTcpSocket 的 TCP 版本,思路一样:连好信号槽,读写字节,DOM 层用 readyRead 驱动。

qidao123.com企服评测-应用市场 编辑提示

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表