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

打印 上一主题 下一主题

主题 673|帖子 673|积分 2019


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.回显服务器



  • ⼀般来说,要先毗连信号槽,再绑定端⼝

    • 假如次序反过来,大概会出现端⼝绑定好了之后,请求就过来了,此时还没来得及毗连信号槽,那么这个请求就有大概错过了

  • 示例
    1. // 构造函数中
    2. {
    3.         socket = new QUdpSocket(this);
    4.         connect(socket, &QUdpSocket::readyRead, this, &Widget::ProcessRequest);
    5.         // 绑定端口号.
    6.         if (!socket->bind(QHostAddress::Any, 2333))
    7.         {
    8.             // 绑定失败!
    9.             QMessageBox::critical(this, "服务器启动出错", socket->errorString());
    10.             return;
    11.         }
    12. }
    13. void Widget::ProcessRequest()
    14. {
    15.     // 1. 读取请求并解析.
    16.     const QNetworkDatagram& req = socket->receiveDatagram();
    17.     QString request = req.data();
    18.    
    19.     // 2. 根据请求计算响应
    20.     const QString& response = Process(request);
    21.    
    22.     // 3. 把响应写回给客户端.
    23.     QNetworkDatagram resp(response.toUtf8(), req.senderAddress(),
    24.                                                   req.senderPort());
    25.     socket->writeDatagram(resp);
    26.    
    27.     // 把这次交互的信息, 显示到界面上.
    28.     QString log = "[" + req.senderAddress().toString() + ":" +
    29.                                 QString::number(req.senderPort()) + "] req: " +
    30.                                 request + ", resp: " + response;
    31.    
    32.     ui->listWidget->addItem(log);
    33. }
    34. QString Widget::Process(const QString &request)
    35. {
    36.     return request;
    37. }
    复制代码

3.回显客户端

  1. // 构造函数中
  2. {
  3.         socket = new QUdpSocket(this);
  4.         // 通过信号槽, 来处理服务器返回的数据.
  5.         connect(socket, &QUdpSocket::readyRead, this, &Widget::ProcessResponse);
  6. }
  7. void Widget::on_pushButton_clicked()
  8. {
  9.     // 1. 获取到输入框的内容
  10.     const QString& text = ui->lineEdit->text();
  11.    
  12.     // 2. 构造 UDP 的请求数据
  13.     QNetworkDatagram req(text.toUtf8(), QHostAddress(SERVER_IP), SERVER_PORT);
  14.    
  15.     // 3. 发送请求数据
  16.     socket->writeDatagram(req);
  17.    
  18.     // 4. 把发送的请求也添加到列表框中.
  19.     ui->listWidget->addItem("客户端说: " + text);
  20.    
  21.     // 5. 把输入框的内容也清空一下.
  22.     ui->lineEdit->setText("");
  23. }
  24. // 通过这个函数来处理收到的响应
  25. void Widget::ProcessResponse()
  26. {
  27.     // 1. 读取到响应数据
  28.     const QNetworkDatagram& resp = socket->receiveDatagram();
  29.     QString response = resp.data();
  30.    
  31.     // 2. 把响应数据显示到界面上.
  32.     ui->listWidget->addItem("服务器说: " + response);
  33. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

欢乐狗

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表