• 【QT】Qt中Websocket的使用


    一、WebSocket的定义

            WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。        

            WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。想对应http协议来说,websocket更加的平等,在http协议中,只有客户端向服务器发送申请请求之后,服务器才会返回请求的数据,如果要保证实时性的话,就需要不断地轮询,每隔一段时间就向服务器发送一个请求,这样就会造成很大的开销,而WebSocket服务器主动向客户端发送数据,而不需要申请,客户端发送数据给服务器也是如此

            简单来说,就是浏览器和服务器之间通信的一种协议,相比较http来说,数据交换更加平等,开销更小;

    二、服务器和客户端

            要想在Qt实现websocket那么我们主要的就是实现一个服务器,由网页实现一个客户端

    2.1 服务器的实现

            要实现服务器,首先要认识QWebSocketServer Class,我们需要通过这个类实现

     1)类分析

            从上图可以知道,需要在.pro文件中添加QT+=websockets,然后添加头文件,新建一个WebSocketTest窗口应用程序,试图如下

    2)添加库

            在WebSocketTest中添加下面的语句

    QT       += websockets
    

    3)添加头文件

            在websockettest.h中添加头文件,声明变量

    1. #ifndef WEBSOCKETTEST_H
    2. #define WEBSOCKETTEST_H
    3. #include
    4. #include
    5. QT_BEGIN_NAMESPACE
    6. namespace Ui { class WebSocketTest; }
    7. QT_END_NAMESPACE
    8. class WebSocketTest : public QWidget
    9. {
    10. Q_OBJECT
    11. public:
    12. WebSocketTest(QWidget *parent = nullptr);
    13. ~WebSocketTest();
    14. private:
    15. Ui::WebSocketTest *ui;
    16. //声明QWebSocketServer变量
    17. QWebSocketServer *web_server;
    18. };
    19. #endif // WEBSOCKETTEST_H

    4)QWebSocketServer类的使用

            再来看一看关于这个类的使用,类名上面F1进入帮助界面,可以看到

    翻译过来就是

    QWebSocketServer是一个基于QTcpServer模型的类,用于处理WebSocket协议的服务器端通信。如果你知道如何使用QTcpServer,你就可以很轻松的使用QWebSocketServer。

    QWebSocketServer类主要用于接收并处理来自客户端的WebSocket连接,你可以手动设定服务端的端口,也可以让QWebSocketServer自动选择。调用listen()函数即可让服务器开始侦听连接请求。

    每当有新的客户端尝试连接服务器时,newConnection()信号就会发出。服务器可以调用nextPendingConnection()方法接受这个握手请求,同时返回一个已经连接状态的QWebSocket对象指针,服务器即可通过这个指针和客户端进行通信。

    如果在过程中发生错误,serverError()方法可以获取错误类型,同时可以调用errorString()方法获取人类可读的错误描述。

    当服务器侦听连接请求时,可以通过serverAddress()和serverPort()来获取服务器正在侦听的地址和端口。调用close()函数可以使QWebSocketServer停止侦听连接请求。

    QWebSocketServer当前还不支持WebSocket拓展和WebSocket子协议。该类仅支持RFC 6455中规定的WebSocket协议的13版。

    有一个默认的握手超时设置为10秒,主要用于防止拒绝服务攻击,该超时时间可以通过setHandshakeTimeout()自定义。

    参见WebSocket Server Example和QWebSocket。

            也就是说使用listen函数监听连接请求,一旦有新的客户端连接,就可以触发newConnection()信号,再由服务器通过nextPendingConnection()方法接收这个客户端的连接,这个方法返回一个QWebsocket的对象指针,通过这个指针就可以和客户端通信了

    5)代码实现

            首先客户端代码我这里直接提供一个可以测试的html,新建一个文本文件,将下面内容复制进去,保存后,将后缀改为html,点击使用浏览器打开。

    1. html>
    2. <html>
    3. WebSocket Test
    4. <body>
    5. <button id="testButton">Send Test Messagebutton>
    6. <div id="messageDisplay">div>

    服务器相关代码

    构造函数

    1. web_server = new QWebSocketServer("Myserver",QWebSocketServer::NonSecureMode,this);
    2. if(web_server->listen(QHostAddress::Any,15678))
    3. {
    4. qDebug()<<"开始监听";
    5. connect(web_server,&QWebSocketServer::newConnection,this,&WebSocketTest::newCilentConnect);
    6. }

    槽函数

    1. void WebSocketTest::newCilentConnect()
    2. {
    3. //返回客户端
    4. web_client = web_server->nextPendingConnection();
    5. qDebug() << "有新的 WebSocket 客户端连接。";
    6. }

    编译运行服务器,然后点击html文件,可以发现会打印”有新的 WebSocket 客户端连接“;

    6)接收客户端的消息

    1. void WebSocketTest::newCilentConnect()
    2. {
    3. //返回客户端
    4. web_client = web_server->nextPendingConnection();
    5. qDebug() << "有新的 WebSocket 客户端连接。";
    6. // 处理接收到的消息
    7. connect(web_client , &QWebSocket::textMessageReceived, this, &WebSocketTest::onTextMessageReceived);
    8. }
    9. void WebSocketTest::onTextMessageReceived(const QString &message)
    10. {
    11. qDebug() << "收到客户端消息:" << message;
    12. if(message=="Test")
    13. {
    14. /*在这里执行你实现的操作,如网页一个按钮,点击后发送打开摄像头信息给服务器,
    15. 服务器执行打开摄像头的操作*/
    16. }
    17. }

            编译运行,点击网页上的按钮,服务器就可以收到这个消息了;

    2.2 客户端的实现

            到前面为止就可以实现客户端发送数据到服务器的操作,现在实现服务器发送数据给客户端

    1. // 向客户端发送数据
    2. void WebSocketTest::sendClientData(const QString &str)
    3. {
    4. if (web_client->isValid()) {
    5. web_client->sendTextMessage(str);
    6. }
    7. }

    然后在界面上添加一个按钮发送信息给客户端

    1. void WebSocketTest::on_btn_send_clicked()
    2. {
    3. sendClientData("Hello");
    4. }

    编译运行,刷新网页后,点击按钮查看效果

     三、完整源码

    websocket.c

    1. #include "websockettest.h"
    2. #include "ui_websockettest.h"
    3. WebSocketTest::WebSocketTest(QWidget *parent)
    4. : QWidget(parent)
    5. , ui(new Ui::WebSocketTest)
    6. {
    7. ui->setupUi(this);
    8. // 创建 WebSocket 服务器
    9. web_server = new QWebSocketServer("Myserver",QWebSocketServer::NonSecureMode,this);
    10. //监听
    11. if(web_server->listen(QHostAddress::Any,15678))
    12. {
    13. qDebug()<<"开始监听";
    14. connect(web_server,&QWebSocketServer::newConnection,this,&WebSocketTest::newCilentConnect);
    15. }
    16. }
    17. void WebSocketTest::newCilentConnect()
    18. {
    19. web_client = web_server->nextPendingConnection();
    20. qDebug() << "有新的 WebSocket 客户端连接。";
    21. // 处理客户端断开连接
    22. connect(web_client, &QWebSocket::disconnected, this, [this, web_client]() {
    23. qDebug() << "WebSocket 客户端断开连接。";
    24. web_client->deleteLater();
    25. });
    26. // 处理接收到的消息
    27. connect(web_client, &QWebSocket::textMessageReceived, this, &WebSocketTest::onTextMessageReceived);
    28. }
    29. void WebSocketTest::onTextMessageReceived(const QString &message)
    30. {
    31. qDebug() << "收到客户端消息:" << message;
    32. }
    33. // 向客户端发送数据
    34. void WebSocketTest::sendClientData(const QString &str)
    35. {
    36. if (web_client->isValid()) {
    37. web_client->sendTextMessage(str);
    38. }
    39. }
    40. void WebSocketTest::on_btn_send_clicked()
    41. {
    42. sendClientData("Hello");
    43. }
    44. WebSocketTest::~WebSocketTest()
    45. {
    46. delete ui;
    47. }

    websocket.h

    1. #ifndef WEBSOCKETTEST_H
    2. #define WEBSOCKETTEST_H
    3. #include
    4. #include
    5. #include
    6. #include
    7. QT_BEGIN_NAMESPACE
    8. namespace Ui { class WebSocketTest; }
    9. QT_END_NAMESPACE
    10. class WebSocketTest : public QWidget
    11. {
    12. Q_OBJECT
    13. public:
    14. WebSocketTest(QWidget *parent = nullptr);
    15. ~WebSocketTest();
    16. private:
    17. Ui::WebSocketTest *ui;
    18. //声明QWebSocketServer变量 服务器
    19. QWebSocketServer *web_server;
    20. //客户端
    21. QWebSocket* web_client;
    22. private slots:
    23. //客户端连接槽函数
    24. void newCilentConnect();
    25. //接收新客户端消息函数
    26. void onTextMessageReceived(const QString &message);
    27. //发送消息给客户端函数
    28. void on_btn_send_clicked();
    29. private:
    30. //发送消息给客户端
    31. void sendClientData(const QString &str);
    32. };
    33. #endif // WEBSOCKETTEST_H

    websocket.html

    1. html>
    2. <html>
    3. WebSocket Test
    4. <body>
    5. <button id="testButton">Send Test Messagebutton>
    6. <div id="messageDisplay">div>

  • 相关阅读:
    几十万换来的DDoS攻击防护经验(转载)
    惊了!10万字的Spark全文!
    分布式定时任务
    等保三级安全要求简要攻略-安全物理环境
    To_Heart—题解——CF1592F1
    ubuntu linux 环境下的程序打包
    windows编程基础概念
    gRPC 拦截器 & 自定义命名解析
    作为测试工程师的发展之路-如何做好测试开开发?
    Tranalyzer2安装及简单使用教程
  • 原文地址:https://blog.csdn.net/weixin_62370184/article/details/140994642