[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概览

主要的类有两个:QUdpSocketQNetworkDatagramQUdpSocket表⽰⼀个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);

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。