马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
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企服评测-应用市场 编辑提示 |