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


0.概述

  • 要使用Qt中有关网络编程的API,需要添加network模块

1.UDP Socket

1.核心API概览

  • 主要的类有两个:QUdpSocketQNetworkDatagram
  • 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);
}
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DieSnowK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值