[Qt][Qt 网络][上]详细讲解
DieSnowK 2024-08-20 10:07:03 阅读 85
目录
0.概述1.UDP Socket1.核心API概览2.回显服务器3.回显客户端
0.概述
要使用Qt中有关网络编程的API,需要添加<code>network模块
1.UDP Socket
1.核心API概览
主要的类有两个:QUdpSocket
和QNetworkDatagram
QUdpSocket
表⽰⼀个UDP的socket⽂件
bind(const QHostAddress&, quint16)
:绑定指定的端口号
成员方法对应原生API:bind()
receiveDatagram()
:返回QNetworkDatagram
,读取⼀个UDP数据报
成员方法对应原生API:recvfrom()
writeDatagram(const QNetworkDatagram&)
:发送⼀个UDP数据报
成员方法对应原生API:sendto()
readyRead()
:在收到数据并准备就绪后触发
信号类似于IO多路复用的通知机制 QNetworkDatagram
表⽰⼀个UDP数据报
QNetworkDatagram(const QByteArray&, const QHostAddress&, quint16)
:
通过QByteArray
,⽬标IP地址,⽬标端⼝号构造⼀个UDP数据报通常⽤于发送数据时 data()
:获取数据报内部持有的数据,返回`QByteArraysenderAddress()
:获取数据报中包含的对端的IP地址senderPort()
:获取数据报中包含的对端的端⼝号
2.回显服务器
⼀般来说,要先连接信号槽,再绑定端⼝
如果顺序反过来,可能会出现端⼝绑定好了之后,请求就过来了,此时还没来得及连接信号槽,那么这个请求就有可能错过了 示例:
// 构造函数中
{
socket = new QUdpSocket(this);
connect(socket, &QUdpSocket::readyRead, this, &Widget::ProcessRequest);
// 绑定端口号.
if (!socket->bind(QHostAddress::Any, 2333))
{
// 绑定失败!
QMessageBox::critical(this, "服务器启动出错", socket->errorString());
return;
}
}
void Widget::ProcessRequest()
{
// 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);
// 把这次交互的信息, 显示到界面上.
QString log = "[" + req.senderAddress().toString() + ":" +
QString::number(req.senderPort()) + "] req: " +
request + ", resp: " + response;
ui->listWidget->addItem(log);
}
QString Widget::Process(const QString &request)
{
return request;
}
3.回显客户端
// 构造函数中
{
socket = new QUdpSocket(this);
// 通过信号槽, 来处理服务器返回的数据.
connect(socket, &QUdpSocket::readyRead, this, &Widget::ProcessResponse);
}
void Widget::on_pushButton_clicked()
{
// 1. 获取到输入框的内容
const QString& text = ui->lineEdit->text();
// 2. 构造 UDP 的请求数据
QNetworkDatagram req(text.toUtf8(), QHostAddress(SERVER_IP), SERVER_PORT);
// 3. 发送请求数据
socket->writeDatagram(req);
// 4. 把发送的请求也添加到列表框中.
ui->listWidget->addItem("客户端说: " + text);
// 5. 把输入框的内容也清空一下.
ui->lineEdit->setText("");
}
// 通过这个函数来处理收到的响应
void Widget::ProcessResponse()
{
// 1. 读取到响应数据
const QNetworkDatagram& resp = socket->receiveDatagram();
QString response = resp.data();
// 2. 把响应数据显示到界面上.
ui->listWidget->addItem("服务器说: " + response);
}
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。