通信TCP

TCP

在 Qt 中,QTcpServerQTcpSocket 是用于实现 TCP 网络通信的核心类。QTcpServer 用于创建 TCP 服务器,监听客户端的连接请求;QTcpSocket 用于实现客户端和服务器之间的数据传输。

通信流程

服务器

  1. 创建套接字服务器QTcpServer对象

  2. 通过QTcpServer对象设置监听,即:QTcpServer::listen()

  3. 基于QTcpServer::newConnection()信号检测是否有新的客户端连接

  4. 如果有新的客户端连接调用QTcpSocket *QTcpServer::nextPendingConnection()得到通信的套接字对象

  5. 使用通信的套接字对象QTcpSocket和客户端进行通信

    #include "mainwindow.h"

    #include "ui_mainwindow.h"

    #include<QMessageBox>

    MainWindow::MainWindow(QWidget *parent) :

     QMainWindow(parent),
    
     ui(new Ui::MainWindow)
    

    {

     ui->setupUi(this);
    
    
    
     tcpserver = new QTcpServer(this);
    

    }

    MainWindow::~MainWindow()

    {

     delete ui;
    

    }

    void MainWindow::on_openBt_clicked()

    {

     quint16 port = ui->portEdit->text().toUInt();  // 获取端口号
    
     if (port == 0 || port > 65535) {
    
         QMessageBox::warning(this, "错误", "端口号无效!");
    
         return;
    
     }
    
     if (!tcpserver->listen(QHostAddress::Any, port)) {
    
         QMessageBox::warning(this, "错误", "服务器启动失败!");
    
         return;
    
     }
    
     QMessageBox::information(this, "成功", "服务器已启动!");
    
    
    
     connect(tcpserver, &QTcpServer::newConnection, this, [=]() {
    
         QTcpSocket *socket = tcpserver->nextPendingConnection();
    
         clientSockets.append(socket);  // 将新客户端 socket 加入列表
    
    
    
         // 处理客户端数据
    
         connect(socket, &QTcpSocket::readyRead, this, [=]() {
    
             QByteArray data = socket->readAll();
    
             ui->recvEdit->appendPlainText("客户端 say:" + data);
    
         });
    
    
    
         // 处理客户端断开连接
    
         connect(socket, &QTcpSocket::disconnected, this, [=]() {
    
             clientSockets.removeOne(socket);  // 从列表中移除
    
             socket->deleteLater();  // 释放资源
    
         });
    
     });
    

    }

    void MainWindow::on_sendBt_clicked()

    {

     // 获取输入框中的文本
    
     QString str = ui->sendEdit->text();  // 假设 sendEdit 是 QLineEdit
    
     if (str.isEmpty()) {
    
         QMessageBox::warning(this, "错误", "发送内容不能为空!");
    
         return;
    
     }
    
    
    
     // 将 QString 转换为 QByteArray
    
     QByteArray data = str.toUtf8();
    
    
    
     // 遍历所有客户端 socket,发送数据
    
     for (QTcpSocket *socket : clientSockets) {
    
         if (socket->state() == QAbstractSocket::ConnectedState) {// 是用于检查 QTcpSocket 是否处于连接状态的条件。
    
             socket->write(data);  // 发送数据
    
         }
    
     }
    
    
    
     // 清空输入框
    
     ui->sendEdit->clear();
    

    }

    void MainWindow::on_closeBt_clicked()

    {

     // 关闭服务器,停止监听
    
     tcpserver->close();
    
    
    
     // 断开所有客户端连接
    
     for (QTcpSocket *socket : clientSockets) {
    
         if (socket->state() == QAbstractSocket::ConnectedState) {
    
             socket->disconnectFromHost();  // 断开连接
    
         }
    
         socket->deleteLater();  // 释放资源
    
     }
    
    
    
     // 清空客户端列表
    
     clientSockets.clear();
    
    
    
     // 更新 UI 状态
    
     QMessageBox::information(this, "成功", "服务器已关闭!");
    
     ui->recvEdit->appendPlainText("服务器已关闭!");
    

    }

头文件

#include <QTcpServer>

#include <QTcpSocket>

  

namespace Ui {

class MainWindow;

}

  

class MainWindow : public QMainWindow

{

    Q_OBJECT

  

public:

    explicit MainWindow(QWidget *parent = 0);

    ~MainWindow();


private slots:

    void on_openBt_clicked();

    void on_sendBt_clicked();

 
    void on_closeBt_clicked();

  

private:

    Ui::MainWindow *ui;

    QTcpServer *tcpserver;

    QList<QTcpSocket*> clientSockets;  // 保存所有客户端连接的 socket 列表

};

客户端

  1. 创建通信的套接字类QTcpSocket对象

  2. 使用服务器端绑定的IP和端口连接服务器QAbstractSocket::connectToHost()

  3. 使用QTcpSocket对象和服务器进行通信

    #include "ui_mainwindow.h"

    #include<QMessageBox>

    MainWindow::MainWindow(QWidget *parent) :

     QMainWindow(parent),
    
     ui(new Ui::MainWindow)
    

    {

     ui->setupUi(this);
    
    
    
      tcpsocket = new QTcpSocket(this);
    
    
    
      // 连接 socket 的信号和槽
    
      connect(tcpsocket, &QTcpSocket::connected, this, [=]() {
    
          QMessageBox::information(this, "成功", "已连接到服务器!");
    
          ui->recvEdit->appendPlainText("已连接到服务器!");
    
      });
    
    
    
      connect(tcpsocket, &QTcpSocket::disconnected, this, [=]() {
    
          QMessageBox::information(this, "提示", "已断开与服务器的连接!");
    
          ui->recvEdit->appendPlainText("已断开与服务器的连接!");
    
      });
    
    
    
      connect(tcpsocket, &QTcpSocket::readyRead, this, [=]() {
    
          QByteArray data = tcpsocket->readAll();
    
          ui->recvEdit->appendPlainText("服务器 say: " + QString::fromUtf8(data));
    
      });
    

    }

    MainWindow::~MainWindow()

    {

     delete ui;
    

    }

    void MainWindow::on_connect_clicked()

    {

     // 获取服务器地址和端口号
    
     QString address = ui->IPEdit->text();
    
     quint16 port = ui->portEdit->text().toUInt();
    
    
    
     if (address.isEmpty() || port == 0) {
    
         QMessageBox::warning(this, "错误", "服务器地址或端口号无效!");
    
         return;
    
     }
    
    
    
     // 连接到服务器
    
     tcpsocket->connectToHost(address, port);
    
    
    
     // 检查连接状态
    
     if (!tcpsocket->waitForConnected(1000)) {
    
         QMessageBox::warning(this, "错误", "连接服务器超时!");
    
     }
    

    }

    void MainWindow::on_disconnect_clicked()

    {

     // 断开与服务器的连接
    
     if (tcpsocket->state() == QAbstractSocket::ConnectedState) {
    
         tcpsocket->disconnectFromHost();
    
     }
    

    }

    void MainWindow::on_sendBt_clicked()

    {

     // 获取输入框中的文本
    
     QString str = ui->sendEdit->text();  // 假设 sendEdit 是 QLineEdit
    
     if (str.isEmpty()) {
    
         QMessageBox::warning(this, "错误", "发送内容不能为空!");
    
         return;
    
     }
    
    
    
     // 将 QString 转换为 QByteArray
    
     QByteArray data = str.toUtf8();
    
    
    
     // 发送数据
    
     if (tcpsocket->state() == QAbstractSocket::ConnectedState) {
    
         tcpsocket->write(data);
    
     } else {
    
         QMessageBox::warning(this, "错误", "未连接到服务器!");
    
     }
    
    
    
     // 清空输入框
    
     ui->sendEdit->clear();
    

    }

头文件

#include <QTcpSocket>

namespace Ui {

class MainWindow;

}

  

class MainWindow : public QMainWindow

{

    Q_OBJECT

  

public:

    explicit MainWindow(QWidget *parent = 0);

    ~MainWindow();

  

private slots:

  

  

    void on_sendBt_clicked();

  

    void on_connect_clicked();

  

    void on_disconnect_clicked();

  

private:

    Ui::MainWindow *ui;

  

    QTcpSocket* tcpsocket;  // 保存所有客户端连接的 socket 列表

  

};

作者: 苏丙榅

链接: 基于TCP的Qt网络通信 | 爱编程的大丙

来源: 爱编程的大丙

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关推荐
Hetertopia3 分钟前
在Vscode开发QT,完成QT环境的配置
开发语言·qt
Neil__Hu2 小时前
Go的基本语法学习与练习
java·c语言·c++·python·qt·学习·golang
寒页_2 小时前
【PyQt5项目实战分享】基于YOLOv5的交通道路目标检测和数据分析软件
python·qt·yolo·目标检测·pyqt
_GR2 小时前
Qt开发⑪Qt网络+Qt音视频_使用实操
开发语言·c++·qt
果汁分你一半l6 小时前
QT实现计算器
开发语言·qt
阳光的错6 小时前
QT day2
开发语言·qt
冰红茶兑滴水10 小时前
Qt 文件操作+多线程+网络
网络·qt
web1376560764315 小时前
RabbitMQ介绍以及基本使用
qt·rabbitmq·ruby
秋已杰爱18 小时前
Qt显示一个hello world
开发语言·qt