您现在的位置是:首页 >学无止境 >Qt下QTcpServer服务端识别多个QTcpSocket客户端网站首页学无止境

Qt下QTcpServer服务端识别多个QTcpSocket客户端

cgsthtm 2024-07-12 12:01:07
简介Qt下QTcpServer服务端识别多个QTcpSocket客户端

Qt官方文档

QTcpSocket Class :https://doc.qt.io/qt-5/qtcpsocket.html
QAbstractSocket Class:https://doc.qt.io/qt-5/qabstractsocket.html
QTcpServer Class:https://doc.qt.io/qt-5/qtcpserver.html

编写QTcpServerDemo和QTcpSocketDemo

看一下效果先:

在这里插入图片描述

实现QTcpServerDemo

头文件:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QNetworkConfigurationManager>
#include <QNetworkInterface>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
public slots:
	/// 服务端接收到客户端连接的槽函数
    void TcpServerConnected();
    /// 服务端接收客户端发送的数据的槽函数
    void ReadAllData();
    /// 客户端连接断开的槽函数
    void ClientDisconnected();

private slots:
	/// 点击启动按钮
    void on_btnRun_clicked();

private:
    Ui::MainWindow *ui;
    /// QTcpServer是服务端
    QTcpServer *tcpServer = nullptr;
    /// QTcpSocket是服务端程序用来与客户端进行通信的
    QTcpSocket *tcpSocket = nullptr;
    /// 用来存储来自客户端的连接
    QList<QTcpSocket*> tcpSocketList;

};
#endif // MAINWINDOW_H

源文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    tcpServer = new QTcpServer(this); // 构造函数中实例化tcpServer
    connect(tcpServer,&QTcpServer::newConnection,this,&MainWindow::TcpServerConnected); // 当有客户端连接到服务端就执行TcpServerConnected槽函数
}

MainWindow::~MainWindow()
{
    delete ui;
    for(auto client : tcpSocketList)
        client->close();
}

/// 点击启动按钮
void MainWindow::on_btnRun_clicked()
{
    QHostAddress address = QHostAddress("127.0.0.1"); // ip
    int port = 5023; // 端口
    if(tcpServer->isListening()) // 判断服务端是否开启了监听
    {
        tcpServer->close()
        for(auto client : tcpSocketList)
            client->close();
        tcpSocketList.clear();
        ui->label->setText(QString("关闭监听成功,%1:%2").arg(address.toString()).arg(port));
        ui->btnRun->setText("开启");
    }
    else
    {
        if(!tcpServer->listen(address,port)) // 服务端开启监听
            ui->label->setText(QString("开启监听失败,%1:%2").arg(address.toString()).arg(port));
        else
        {
            ui->label->setText(QString("开启监听成功,%1:%2").arg(address.toString()).arg(port));
            ui->btnRun->setText("关闭");
        }
    }

}

/// 当有客户端连接到服务端
void MainWindow::TcpServerConnected()
{
    tcpSocket = tcpServer->nextPendingConnection();
    if(!tcpSocketList.contains(tcpSocket))
        tcpSocketList.append(tcpSocket);
    connect(tcpSocket,&QTcpSocket::readyRead,this,&MainWindow::ReadAllData);
    connect(tcpSocket,&QTcpSocket::disconnected,this,&MainWindow::ClientDisconnected);
    ui->txtLog->append(tcpSocket->localAddress().toString() + " 已连接");
}

/// 服务端接收客户端发送的数据
void MainWindow::ReadAllData()
{
    QTcpSocket *client = dynamic_cast<QTcpSocket*>(sender());
    QByteArray buff = client->readAll();
    qDebug() << buff;
    ui->txtLog->append(buff);
    client->write(buff);
}

/// 当关闭与客户端的连接时
void MainWindow::ClientDisconnected()
{
    QTcpSocket *client = dynamic_cast<QTcpSocket*>(sender());
    QString msg = QString("触发断开连接,%1:%2").arg(client->peerAddress().toString()).arg(client->peerPort());
    qDebug() << msg;
    ui->txtLog->append(msg);
}

实现QTcpSocketDemo

头文件:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QTcpServer>
#include <QNetworkInterface>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:
    void ReadAllData();
    void Connected();
    void Disconnected();

private slots:
    void on_btnSend_clicked();

    void on_btnDisconnect_clicked();

private:
    Ui::MainWindow *ui;
    QTcpSocket *tcpSocket = nullptr;
    QHostAddress address;
    int port;
};
#endif // MAINWINDOW_H

源文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    tcpSocket = new QTcpSocket(this);
    connect(tcpSocket,&QTcpSocket::readyRead,this,&MainWindow::ReadAllData);
    connect(tcpSocket,&QTcpSocket::connected,this,&MainWindow::Connected);
    connect(tcpSocket,&QTcpSocket::disconnected,this,&MainWindow::Disconnected);
    address = QHostAddress("127.0.0.1");
    port = 5023;
    ui->txtIp->setText(address.toString());
    ui->txtPort->setText(QString::number(port));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::ReadAllData()
{
    QByteArray buff = tcpSocket->readAll();
    qDebug() << buff;
    ui->txtLog->append(buff);
}

void MainWindow::Connected()
{
    QString address = tcpSocket->peerAddress().toString();
    int port = tcpSocket->peerPort();
    qDebug() << QString("连接成功, %1:%2").arg(address).arg(port);
    ui->txtLog->append(QString("连接成功, %1:%2").arg(address).arg(port));
}

void MainWindow::Disconnected()
{
    ui->txtIp->setEnabled(true);
    ui->txtPort->setEnabled(true);
    ui->btnSend->setText("连接");
}

void MainWindow::on_btnSend_clicked()
{
    QString txt = ui->txtSend->toPlainText();
    tcpSocket->write(txt.toStdString().c_str());
}

void MainWindow::on_btnDisconnect_clicked()
{
    address = QHostAddress(ui->txtIp->text());
    port = ui->txtPort->text().toInt();
    if(tcpSocket->state() == QTcpSocket::SocketState::ConnectedState)
    {
        ui->txtIp->setEnabled(true);
        ui->txtPort->setEnabled(true);
        tcpSocket->disconnectFromHost();
        ui->btnDisconnect->setText("连接");
    }
    else
    {
        ui->txtIp->setEnabled(false);
        ui->txtPort->setEnabled(false);
        tcpSocket->connectToHost(address.toString(),port);
        ui->btnDisconnect->setText("断开");
    }
}

使用windeployqt生成程序运行所需依赖文件

确认编译环境:

在这里插入图片描述
在对应编译环境目录下运行 windeployqt 生成运行程序所需的依赖文件:

在这里插入图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。