qt QWebSocket详解

发布于:2025-09-04 ⋅ 阅读:(16) ⋅ 点赞:(0)

1、概述

QWebSocket是Qt网络模块中的一个类,用于实现WebSocket协议的通信。WebSocket是一种全双工的通信协议,允许在客户端和服务器之间建立实时的双向通信。QWebSocket提供了对WebSocket协议的支持,使得开发者能够在Qt应用中方便地实现实时通信功能。它在需要实时数据传输、消息推送等场景中非常常见,如聊天室、实时数据流、在线游戏等

2、重要方法

  • QWebSocket(const QString &origin = QString(), QWebSocketProtocol::Version version = QWebSocketProtocol::VersionLatest, QObject *parent = nullptr):构造函数,用于创建一个QWebSocket对象。origin参数指定了WebSocket连接的来源,version参数指定了WebSocket协议的版本,parent参数指定了父对象。

  • virtual ~QWebSocket() override:析构函数,用于销毁QWebSocket对象。

  • void abort():立即关闭WebSocket连接,不发送关闭帧。

  • qint64 bytesToWrite() const:返回待发送的字节数。

  • QWebSocketProtocol::CloseCode closeCode() const:返回WebSocket连接关闭的原因代码。

  • QString closeReason() const:返回WebSocket连接关闭的原因文本。

  • QAbstractSocket::SocketError error() const:返回最近一次发生的错误类型。

  • QString errorString() const:返回最近一次错误的描述信息。

  • bool flush():尝试将所有待发送的数据发送出去。

  • void ignoreSslErrors(const QList<QSslError> &errors):忽略指定的SSL错误。

  • bool isValid() const:检查WebSocket连接是否有效。

  • QHostAddress localAddress() const:返回本机的IP地址。

  • quint16 localPort() const:返回本机的端口号。

  • const QMaskGenerator *maskGenerator() const:返回当前使用的掩码生成器。

  • QString origin() const:返回WebSocket连接的来源。

  • QAbstractSocket::PauseModes pauseMode() const:返回当前的暂停模式。

  • QHostAddress peerAddress() const:返回对端的IP地址。

  • QString peerName() const:返回对端的主机名。

  • quint16 peerPort() const:返回对端的端口号。

  • QNetworkProxy proxy() const:返回当前使用的代理。

  • qint64 readBufferSize() const:返回读取缓冲区的大小。

  • QNetworkRequest request() const:返回当前的网络请求。

  • QUrl requestUrl() const:返回请求的URL。

  • QString resourceName() const:返回资源名称。

  • void resume():恢复暂停的连接。

  • qint64 sendBinaryMessage(const QByteArray &data):发送一个二进制消息。

  • qint64 sendTextMessage(const QString &message):发送一个文本消息。

  • void setMaskGenerator(const QMaskGenerator *maskGenerator):设置掩码生成器。

  • void setPauseMode(QAbstractSocket::PauseModes pauseMode):设置暂停模式。

  • void setProxy(const QNetworkProxy &networkProxy):设置代理。

  • void setReadBufferSize(qint64 size):设置读取缓冲区的大小。

  • void setSslConfiguration(const QSslConfiguration &sslConfiguration):设置SSL配置。

  • QSslConfiguration sslConfiguration() const:返回当前的SSL配置。

  • QAbstractSocket::SocketState state() const:返回当前的连接状态。

  • QWebSocketProtocol::Version version() const:返回当前使用的WebSocket协议版本。

  • void close(QWebSocketProtocol::CloseCode closeCode = QWebSocketProtocol::CloseCodeNormal, const QString &reason = QString()):关闭WebSocket连接,可以指定关闭代码和原因。

  • void ignoreSslErrors():忽略所有SSL错误。

  • void open(const QNetworkRequest &request):使用QNetworkRequest打开WebSocket连接。

  • void open(const QUrl &url):使用URL打开WebSocket连接。

  • void ping(const QByteArray &payload = QByteArray()):发送一个Ping帧,可选地携带负载。

3、信号

  • void aboutToClose():即将关闭连接时发出。

  • void binaryFrameReceived(const QByteArray &frame, bool isLastFrame):收到二进制帧时发出。

  • void binaryMessageReceived(const QByteArray &message):收到二进制消息时发出。

  • void bytesWritten(qint64 bytes):成功写入字节时发出。

  • void connected():连接成功时发出。

  • void disconnected():连接断开时发出。

  • void error(QAbstractSocket::SocketError error):发生错误时发出。

  • void pong(quint64 elapsedTime, const QByteArray &payload):收到Pong响应时发出。

  • void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator):需要预共享密钥认证时发出。

  • void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator):需要代理认证时发出。

  • void readChannelFinished():读取通道关闭时发出。

  • void sslErrors(const QList<QSslError> &errors):SSL错误发生时发出。

  • void stateChanged(QAbstractSocket::SocketState state):连接状态改变时发出。

  • void textFrameReceived(const QString &frame, bool isLastFrame):收到文本帧时发出。

  • void textMessageReceived(const QString &message):收到文本消息时发出。

4、实例

//.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDir>
#include <iomanip>
#include <sstream>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE


#include <QDebug>
#include <QWebSocketServer>
#include <QtWebSockets>


class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    //server
    QWebSocketServer* m_server = nullptr;
    QList<QWebSocket*> m_clients;

    //client
    QWebSocket m_client;
public slots:
    void on_disconnected();
    void on_textMessageReceived(const QString &message);

    void connected();
    void disconnected();
    void textMessageReceived(const QString &message);
private slots:

    void on_pushButton_5_clicked();

    void on_pushButton_6_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_clicked();


    void on_newConnection();            // 有新的客户端连接
    void on_closed();                   // 关闭监听成功
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QLabel>
#include <QVBoxLayout>
#include <QPushButton>
#include <QPushButton>


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


    setWindowTitle("WebSocket");

    m_server = new QWebSocketServer("web服务端", QWebSocketServer::NonSecureMode, this);
    connect(m_server, &QWebSocketServer::newConnection, this, &MainWindow::on_newConnection);
    connect(m_server, &QWebSocketServer::closed, this, &MainWindow::on_closed);

    connect(&m_client, &QWebSocket::connected, this, &MainWindow::connected);
    connect(&m_client, &QWebSocket::textFrameReceived, this, &MainWindow::textMessageReceived);
    connect(&m_client, &QWebSocket::disconnected, this, &MainWindow::disconnected);

}

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

/**
 * @brief 有新的客户端发起连接
 */
void MainWindow::on_newConnection()
{
    QWebSocket* client = m_server->nextPendingConnection();   // 获取连接成功的客户端

    connect(client, &QWebSocket::textMessageReceived, this, &MainWindow::on_textMessageReceived);
    connect(client, &QWebSocket::disconnected, this, &MainWindow::on_disconnected);

    // 将所有客户端加入列表
    m_clients << client;
    ui->textEdit_3->append(QString("[%1:%2] 连接成功!").arg(client->peerAddress().toString()).arg(client->peerPort()));
}

/**
 * @brief 服务端关闭监听,关闭后不再接收新的客户端的连接请求
 */
void MainWindow::on_closed()
{
    ui->textEdit->append("服务端关闭监听!");
    ui->pushButton_5->setText("开启监听");
}


void MainWindow::on_pushButton_5_clicked()
{
    //TcpServer::get()->startServer(ui->lineEdit_5->text().toInt());
    if(!m_server->isListening())
    {
        bool ret = m_server->listen(QHostAddress::AnyIPv4, ui->lineEdit_5->text().toInt());
        if(ret)
        {
            ui->textEdit_3->append(QString("开始监听:%1").arg(m_server->serverUrl().toString()));
            ui->pushButton_5->setText("停止");
        }
    }
    else
    {
        m_server->close();
    }
}

/**
 * @brief 向所有连接的客户端发送数据
 */
void MainWindow::on_pushButton_6_clicked()
{
    QString data = ui->textEdit_4->toPlainText();
    for(auto client : m_clients)
    {
        client->sendTextMessage(data);
    }
}

/**
 * @brief 断开连接时移除对应的客户端
 */
void MainWindow::on_disconnected()
{
    QWebSocket *socket = qobject_cast<QWebSocket *>(sender());
    for(int i = 0; i < m_clients.count(); ++i)
    {
        if(m_clients.at(i) == socket)
        {
            disconnect(socket, &QWebSocket::textMessageReceived, this, &MainWindow::on_textMessageReceived);
            disconnect(socket, &QWebSocket::disconnected, this, &MainWindow::on_disconnected);
            m_clients.removeAt(i);
            break;
        }
    }
    ui->textEdit->append(QString("[%1:%2] 断开连接!").arg(socket->peerAddress().toString()).arg(socket->peerPort()));
}

/**
 * @brief          接收信息并将信息转发给所有客户端
 * @param message
 */
void MainWindow::on_textMessageReceived(const QString &message)
{
    QWebSocket *socket = qobject_cast<QWebSocket *>(sender());
    for(auto client : m_clients)
    {
        if(client != socket)   // 向所有连接的客户端转发信息,除了当前信息的发出者
        {
            client->sendTextMessage(message);
        }
    }
    ui->textEdit_3->append(QString("[%1:%2] %3").arg(socket->peerAddress().toString()).arg(socket->peerPort()).arg(message));
}


void MainWindow::connected()
{
    ui->textEdit_2->append("连接成功!");
}

void MainWindow::disconnected()
{
    ui->textEdit_2->append("断开连接!");
}

/**
 * @brief          接收数据
 * @param message
 */
void MainWindow::textMessageReceived(const QString &message)
{
    ui->textEdit_2->append(message);
}

void MainWindow::on_pushButton_2_clicked()
{
    m_client.open(QUrl(ui->lineEdit->text().trimmed()));
}


void MainWindow::on_pushButton_clicked()
{
    QString data = ui->textEdit->toPlainText();
    if(m_client.state() == QAbstractSocket::ConnectedState)    // 判断是否连接
    {
        m_client.sendTextMessage(data);
    }
}


源码下载:点击跳转​​​​​​​

点击扫码加入群聊

觉得有帮助的话,打赏一下呗。。

           


网站公告

今日签到

点亮在社区的每一天
去签到