news 2026/9/5 7:32:16

Qt_webSocket协议编程实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Qt_webSocket协议编程实战

Qt WebSocket 协议编程实战

1. WebSocket 协议概述

WebSocket 是一种基于单个 TCP 连接提供全双工(Full-Duplex)通信信道的网络技术。与传统的 HTTP 请求/响应模型不同,WebSocket 在连接建立后,客户端与服务器可以双向、实时、低延迟地收发数据,无需反复握手。

  • 标准化:IETF 将其标准化为RFC 6455
  • 握手:通过 HTTP 的Upgrade头完成协议升级(HTTP/1.1 101 Switching Protocols),握手完成后数据在同一个 TCP 连接上以**帧(frame)**的形式传输
  • 协议标识ws://(明文)与wss://(基于 TLS 加密,默认端口 443)
  • 默认端口ws为 80,wss为 443
  • 典型用途:实时聊天、股票/行情推送、在线游戏、服务端主动推送通知等

在 Qt 中,QWebSocket既可用于客户端应用程序,也可用于服务器端(配合QWebSocketServer)构建 WebSocket 服务。


2. QWebSocket Class(客户端)

QWebSocket继承自QObject,用于在客户端发起并管理一个 WebSocket 连接。

2.1 头文件与链接

#include<QWebSocket>
  • 需要在.pro文件中添加:QT += websockets
  • CMake 中:find_package(Qt6 COMPONENTS WebSockets REQUIRED)并链接Qt6::WebSockets

2.2 连接与断开

QWebSocket socket;// 发起连接(异步)socket.open(QUrl("ws://localhost:1234"));// 连接成功信号connect(&socket,&QWebSocket::connected,this,[](){qDebug()<<"Connected";});// 可选:设置是否忽略 SSL 错误(仅用于测试环境,生产谨慎)connect(&socket,&QWebSocket::sslErrors,&socket,QOverload<constQList<QSslError>&>::of(&QWebSocket::ignoreSslErrors));// 主动关闭socket.close();

2.3 收发数据

// 发送文本消息socket.sendTextMessage(QStringLiteral("Hello, Server!"));// 发送二进制消息QByteArray data=QByteArray::fromHex("48656c6c6f");socket.sendBinaryMessage(data);// 接收文本消息connect(&socket,&QWebSocket::textMessageReceived,this,[](constQString&msg){qDebug()<<"Text received:"<<msg;});// 接收二进制消息connect(&socket,&QWebSocket::binaryMessageReceived,this,[](constQByteArray&data){qDebug()<<"Binary received, size:"<<data.size();});

3. QWebSocketServer Class(服务器)

QWebSocketServer用于在服务器端监听并接受 WebSocket 客户端连接,创建一个 WebSocket 服务。

3.1 启动服务器

#include<QWebSocketServer>QWebSocketServerserver(QStringLiteral("My Server"),QWebSocketServer::NonSecureMode);// 明文模式// 或使用 SecureMode(需要配置 SSL 证书)// QWebSocketServer server(QStringLiteral("My Server"),// QWebSocketServer::SecureMode);if(server.listen(QHostAddress::Any,1234)){qDebug()<<"Listening on port"<<server.serverPort();}

3.2 处理新连接与消息

// 新客户端接入connect(&server,&QWebSocketServer::newConnection,this,[&server](){QWebSocket*client=server.nextPendingConnection();qDebug()<<"New client:"<<client->peerAddress().toString();connect(client,&QWebSocket::textMessageReceived,this,[client](constQString&msg){client->sendTextMessage("Echo: "+msg);// 回显});connect(client,&QWebSocket::disconnected,client,&QObject::deleteLater);});

4. 相关 API 一览

4.1 QWebSocket 主要方法

方法说明
open(const QUrl &url)发起连接到指定 WebSocket 地址
close(CloseCode code = NormalClosure)关闭连接
sendTextMessage(const QString &message)发送文本消息
sendBinaryMessage(const QByteArray &data)发送二进制消息
abort()立即中止连接
requestUrl()返回请求的 URL
state()返回当前连接状态(QAbstractSocket::SocketState
error()/errorString()获取错误信息

4.2 QWebSocket 主要信号

信号说明
connected()连接建立成功
disconnected()连接断开
textMessageReceived(const QString &)收到文本消息
binaryMessageReceived(const QByteArray &)收到二进制消息
stateChanged(QAbstractSocket::SocketState)连接状态变化
errorOccurred(QAbstractSocket::SocketError)发生错误
sslErrors(const QList<QSslError> &)SSL 错误

4.3 QWebSocketServer 主要方法

方法说明
listen(const QHostAddress &, quint16 port)开始监听
nextPendingConnection()取出下一个待处理的客户端连接
close()停止监听
hasPendingConnections()是否有待处理的连接
serverPort()返回实际监听的端口

4.4 QWebSocketServer 主要信号

信号说明
newConnection()有新客户端连接
closed()服务器关闭
acceptError(QAbstractSocket::SocketError)接受连接出错

4.5 重要枚举

  • QWebSocketProtocol::Version:协议版本(VersionLatest/Version13等)
  • QWebSocketServer::SslModeNonSecureMode/SecureMode
  • QWebSocketProtocol::CloseCode:关闭码(NormalClosureGoingAway等)

5. 完整实战示例

下面是一个同时包含客户端与服务器的完整示例,便于快速验证。

5.1 服务器端(main.cpp)

#include<QCoreApplication>#include<QWebSocketServer>#include<QWebSocket>#include<QDebug>intmain(intargc,char*argv[]){QCoreApplicationa(argc,argv);QWebSocketServerserver(QStringLiteral("Echo Server"),QWebSocketServer::NonSecureMode);QObject::connect(&server,&QWebSocketServer::newConnection,[&server](){QWebSocket*client=server.nextPendingConnection();qDebug()<<"Client connected:"<<client->peerAddress().toString();QObject::connect(client,&QWebSocket::textMessageReceived,[client](constQString&msg){qDebug()<<"Received:"<<msg;client->sendTextMessage(QStringLiteral("Echo: ")+msg);});QObject::connect(client,&QWebSocket::disconnected,client,&QObject::deleteLater);});if(server.listen(QHostAddress::Any,1234)){qDebug()<<"Server listening on port"<<server.serverPort();}else{qDebug()<<"Listen failed";return1;}returna.exec();}

5.2 客户端端(main.cpp)

#include<QCoreApplication>#include<QWebSocket>#include<QDebug>intmain(intargc,char*argv[]){QCoreApplicationa(argc,argv);QWebSocket socket;QObject::connect(&socket,&QWebSocket::connected,[&socket](){qDebug()<<"Connected, sending message...";socket.sendTextMessage(QStringLiteral("Hello, Server!"));});QObject::connect(&socket,&QWebSocket::textMessageReceived,[](constQString&msg){qDebug()<<"Server said:"<<msg;});QObject::connect(&socket,&QWebSocket::disconnected,&a,&QCoreApplication::quit);// 连接过程中发生错误QObject::connect(&socket,&QWebSocket::errorOccurred,[](QAbstractSocket::SocketError e){qDebug()<<"Error:"<<e;});socket.open(QUrl(QStringLiteral("ws://localhost:1234")));returna.exec();}

5.3 .pro 文件

QT += core websockets CONFIG += c++17 SOURCES += main.cpp

Qt WebSocket 聊天系统 — 服务端 + 客户端案例

项目角色说明
QWebsocketServerPrs服务端消息中转站,监听 8899 端口,管理连接、群发/私发/转发消息
untitled40客户端聊天界面,连接服务器、发送/接收消息

两个项目配套使用才能组成一个完整的多人聊天系统。


1. 两个项目是什么关系

┌─────────────────────┐ ws://192.168.x.x:8899 ┌─────────────────────┐ │ QWebsocketServerPrs │ ◄──────────────────────────────► │ untitled40 │ │ (服务端) │ │ (客户端) │ │ 监听 8899 端口 │ 可有多个客户端同时连接 │ 填写地址+名称连接 │ └─────────────────────┘ └─────────────────────┘
QWebsocketServerPrs(服务端)untitled40(客户端)
核心类QWebSocketServerQWebSocket
数量1 个可以开很多个(多个人聊天)
职责监听端口、管理连接、群发/私发/转发发起连接、发送消息、接收并显示消息

客户端把"自己的名字"当 origin 传给服务器,服务器靠socket->origin()认人、靠 JSON 里的dst转发消息。


整体代码仓库地址

HTTPS:https://github.com/wuyongGitHub/qt-websocket-chat.git

SSH:git@github.com:wuyongGitHub/qt-websocket-chat.git

多客户端连接服务端效果

群发消息效果

私发消息效果

客户端相互发消息效果

整体效果:

6. 常见问题与注意事项

根据前端开发业务流,总结一下websocket使用事项

  • 心跳保活:长时间空闲的连接可能被中间设备断开,建议定期发送 ping(Qt 会自动响应 ping/pong,可手动ping()检测存活)。
  • 线程模型QWebSocket非线程安全,跨线程使用时需通过信号槽或QMetaObject::invokeMethod调度到所属线程。
  • 错误处理:务必连接errorOccurred信号,网络异常时才能及时感知并重连。
  • 大文件传输:二进制消息适合传输大块数据,但需注意分帧与内存占用,必要时自行设计分片协议。
  • 安全:生产环境应使用wss://SecureMode)并正确配置证书,避免明文传输敏感数据。
  • 释放时机:客户端断开连接后,服务器端应及时deleteLater释放QWebSocket对象,防止内存泄漏。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 8:35:46

Linux基础指令上

pwd指令与linux文件结构pwd指令指令&#xff1a;pwd功能&#xff1a;查看别人所处工作目录-bash-4.2# pwd /root -bash-4.2# linux文件结构Linux的文件是一颗多叉树非叶子节点&#xff1a;非空目录。叶子节点&#xff1a;空目录或者普通文件ls指令与常用选项以及linux中的文件1…

作者头像 李华
网站建设 2026/9/5 3:52:23

三菱Q系列PLC填表式通信实现Modbus RTU数据采集与设备控制

在实际工业自动化项目中&#xff0c;PLC与第三方设备&#xff08;如仪表、变频器、传感器&#xff09;的通信是核心需求。三菱Q系列PLC功能强大&#xff0c;但其原生通信指令&#xff08;如RS指令&#xff09;在应对Modbus RTU这类标准协议时&#xff0c;往往需要开发者编写大量…

作者头像 李华
网站建设 2026/9/4 8:25:42

FPGA实战:MIPI CSI-2接收子系统配置与调试全解析

简介&#xff1a;这是基于Xilinx FPGA的MIPI CSI-2接收子系统完整工程&#xff0c;面向在Zynq UltraScale&#xff08;zyqnmp&#xff09;平台上实现摄像头数据接入与HDMI显示输出的硬件开发者&#xff0c;解决MIPI接口信号捕获、通道同步与视频格式转换等关键难题。压缩包共20…

作者头像 李华
网站建设 2026/9/5 7:11:43

冒泡排序可视化:用24个数字讲透算法过程与Python实现

冒泡排序可视化不是用来“欣赏”的&#xff0c;它是把算法过程变成可观察状态的最好方法。这篇文章用24个数字作为排序样本&#xff0c;把冒泡排序从相邻比较、逐趟扫描到每个元素沉底的过程完整拆开&#xff0c;最后给出可以运行的最小可视化程序和排查思路。如果你正在学算法…

作者头像 李华
网站建设 2026/9/2 7:23:53

每日leetcode(这题真的很有意思,第一次搞半天搞错瓶颈在哪)

2948. 交换得到字典序最小的数组 - 力扣&#xff08;LeetCode&#xff09; 代码参考&#xff1a; 并查集【C数据结构进阶】玩转并查集&#xff1a;从原理到实战&#xff0c;C 实现与高频面试题全解析_并查集c-CSDN博客 题目 给你一个下标从 0 开始的 正整数 数组 nums 和一…

作者头像 李华