Qt 学习笔记 - 第四章 - Qt的三驾马车之 - 网络编程

[复制链接]
发表于 2023-3-15 15:05:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
Qt 学习笔记全系列传送门:

  • Qt 学习笔记 - 第一章 - 快速开始、信号与槽
  • Qt 学习笔记 - 第二章 - 添加图片、布局、界面切换
  • Qt 学习笔记 - 第三章 - Qt的三驾马车之一 - 串口编程 + 程序打包成Windows软件
  • 【本章】Qt 学习笔记 - 第四章 - Qt的三驾马车之二 - 网络编程
  • Qt 学习笔记 - 第五章 - Qt 时间编程 - Qt 时钟

目录

  • 1、TCP 通信

    • 1.1 TCP  编程的特点
    • 1.2 TCP 服务器案例
    • 1.3 TCP 客户端案例

  • 2、UDP 通信

    • 1.1 UDP 编程的特点
    • 1.2 UDP 客户端


1、TCP 通信

1.1 TCP  编程的特点


  • 包含服务器和客户端
  • 使用时需要在工程文件中引入 QT += network并在使用时导入包
  • 需要使用到的类有

    • QTcpServer
    • QTcpSocket

1.2 TCP 服务器案例

需要先定义并在构造中初始化QTcpServer *tcpServer和QTcpSocket *tcpSocket:
  1. // 这里传入 this 时,父对象被删除时子对象也会被删除,省去了delete的麻烦
  2. tcpServer = new QTcpServer(this);
  3. tcpSocket = new QTcpSocket(this);
复制代码


  • 工程文件
    1. QT       += core gui network
    复制代码
  • UI

    • 接收框,只读
    • 端口号输入框和提示文字
    • 发送窗口
    • 按钮,打开服务器、关闭服务器、发送
    • 控件改名

  • 逻辑功能

    • 监听:槽函数,点击打开服务器时,需要监听对应端口是否被访问
      1. Widget::Widget(QWidget *parent) :
      2.     QWidget(parent),
      3.     ui(new Ui::Widget)
      4. {
      5.     ui->setupUi(this);
      6.     // 新建tcpServer和tcpSocket的对象,成员属性在头文件中已定义,细节不表
      7.     tcpServer = new QTcpServer(this);
      8.     tcpSocket = new QTcpSocket(this);
      9. }
      10. void Widget::on_openBt_clicked()
      11. {
      12.     // 开启监听,监听所有人的连接,参数指定所有人和一个无符号整型端口
      13.     tcpServer->listen(QHostAddress::Any, ui->portEdit->text().toUInt());
      14. }
      复制代码
    • 接收:包含获取和展示两个部分

      • 获取
        1. Widget::Widget(QWidget *parent) :
        2.     QWidget(parent),
        3.     ui(new Ui::Widget)
        4. {
        5.     ui->setupUi(this);
        6.     tcpServer = new QTcpServer(this);
        7.     tcpSocket = new QTcpSocket(this);
        8.     // 当监测到新的连接产生的信号时,调用槽函数newConnection_Slot()
        9.     connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection_Slot()));
        10. }
        11. void Widget::newConnection_Slot()
        12. {
        13.     // 获取到已经连接的客户端的Socket
        14.     tcpSocket = tcpServer->nextPendingConnection();
        15.     // 当存在可读数据时,调用槽函数readyRead_Slot(),用于展示到接收框中
        16.     connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot()));
        17. }
        复制代码
      • 展示到接收框
        1. void Widget::readyRead_Slot()
        2. {
        3.     // 读取tcpSocket中的内容,使用字符串接收
        4.     QString buf = tcpSocket->readAll();
        5.     // 将读取到的信息展示到接收框中
        6.     ui->recvEdit->appendPlainText(buf);
        7. }
        复制代码

    • 发送
      1. void Widget::on_sendBt_clicked()
      2. {
      3.     // 需要转成 char*
      4.     tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
      5. }
      复制代码
    • 关闭
      1. void Widget::on_closeBt_clicked()
      2. {
      3.     tcpServer->close();
      4.     tcpSocket->close();
      5. }
      复制代码

1.3 TCP 客户端案例


  • 工程文件
    1. QT       += core gui network
    复制代码
  • UI

    • 接收框,只读
    • 端口号输入框和提示文字、IP地址输入框和提示文字
    • 发送窗口
    • 按钮,打开服务器、关闭服务器、发送
    • 控件改名

  • 逻辑功能
    需要先定义并在构造中初始化QTcpSocket *tcpSocket:
    ​        tcpSocket = new QTcpSocket(this);

    • 连接
      1. void Widget::on_openBt_clicked()
      2. {
      3.     // 点击打开客户端时,应连接服务器,取界面上的ip和端口,端口要转Uint
      4.     tcpSocket->connectToHost(ui->ipEdit->text(), ui->portEdit->text().toUInt());
      5.     // 当监听到连接成功的信号connected()时,调用槽函数connected_Slot()
      6.     connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected_Slot()));
      7. }
      复制代码
    • 接收
      1. void Widget::connected_Slot()
      2. {
      3.     // 当监听到有东西可读的信号readyRead()时,调用槽函数
      4.     connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot()));
      5. }
      6. void Widget::readyRead_Slot()
      7. {
      8.     // 读取tcpSocket中的信息,展示到页面上
      9.     ui->recvEdit->appendPlainText(tcpSocket->readAll());
      10. }
      复制代码
    • 发送
      1. void Widget::on_sendBt_clicked()
      2. {
      3.     // 发送时将发送框中的内容转为 char* 写入tcpSocket
      4.     tcpSocket->write(ui->sendEdit->text().toLocal8Bit());
      5. }
      复制代码
    • 关闭
      1. void Widget::on_closeBt_clicked()
      2. {
      3.     tcpSocket->close();
      4. }
      复制代码

2、UDP 通信

1.1 UDP 编程的特点


  • 不分客户端和服务器
  • 使用时需要在工程文件中引入 QT += network并在使用时导入包
  • 需要使用 QUdpSocket 类
1.2 UDP 客户端

需要先定义并在构造中初始化QUdpSocket *udpSocket:
​        udpSocket = new QUdpSocket(this);


  • 工程文件
    1. QT       += core gui network
    复制代码
  • UI

    • 接收框,只读
    • 端口号输入框和提示文字、目标端口号输入框和提示文字、IP地址输入框和提示文字
    • 发送窗口
    • 按钮,打开服务器、关闭服务器、发送
    • 控件改名

  • 逻辑功能

    • 启动
      1. void Widget::on_openBt_clicked()
      2. {
      3.     // 将端口号绑定到Socket
      4.     if (udpSocket->bind(ui->localPortEdit->text().toUInt())) {
      5.         QMessageBox::information(this, "提示", "成功");
      6.     } else {
      7.         QMessageBox::information(this, "提示", "失败");
      8.     }
      9.     // 关联readyRead信号,有可读信号调用槽函数
      10.     connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_slot()));
      11. }
      复制代码
    • 接收
      1. void Widget::readyRead_slot()
      2. {
      3.     // hasPendingDatagrams()用于判断是否读取完,若没有读完则返回true
      4.     while (udpSocket->hasPendingDatagrams()) {
      5.         QByteArray arr;
      6.         // 将数组调整为和 udpSocket 中剩下的数据大小一样
      7.         arr.resize(udpSocket->pendingDatagramSize());
      8.         // 将udpSocket中的信息读取到arr中,参数为接收数组和接收的数据长度
      9.         udpSocket->readDatagram(arr.data(), arr.size());
      10.         // 将信息写到页面上
      11.         QString buffer = arr.data();
      12.         ui->recvEdit->appendPlainText(buffer);
      13.     }
      14. }
      复制代码
    • 发送
      1. void Widget::on_sendBt_clicked()
      2. {
      3.     qunit16 port = ui->aimPortEdit->text().toUInt();
      4.     QString sendbuffer = ui->sendEdit->text();
      5.     QHostAddress addr;
      6.     addr.setAddress(ui->aimIpEdit->text());
      7.     // 发送的内容需要转成 char*
      8.     udpSocket->writeDatagram(sendbuffer.toLocal8Bit().data(), sendbuffer.length(), addr, port);
      9. }
      复制代码
    • 关闭
      1. void Widget::on_closeBt_clicked()
      2. {
      3.     udpSocket->close();
      4. }
      复制代码

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表