欢乐狗 发表于 2024-8-21 12:47:40

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

0.概述



[*]要利用Qt中有关网络编程的API,需要添加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():获取数据报内部持有的数据,返回`QByteArray
[*]senderAddress():获取数据报中包罗的对端的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);
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: [Qt][Qt 网络][上]详细解说