【C++】Qt:WebSocket客户端示例
创作时间:
作者:
@小白创作中心
【C++】Qt:WebSocket客户端示例
引用
CSDN
1.
https://blog.csdn.net/qq_40344790/article/details/136842845
这篇文章主要介绍WebSocket客户端示例。
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,允许在客户端和服务器之间实时交换数据。WebSocket 客户端是指使用 WebSocket 协议与服务器端建立连接并进行数据交换的程序或组件。
实现 WebSocket 客户端的步骤:
- 建立连接: WebSocket 客户端首先需要与服务器建立连接,通常通过 WebSocket URL(ws:// 或 wss://)来连接到服务器。
- 发送和接收数据: 一旦连接建立成功,客户端可以通过发送消息给服务器来交换数据,并从服务器接收响应消息。
- 处理事件: WebSocket 客户端可以监听连接状态、错误和消息等事件,并根据需要处理这些事件。
- 关闭连接: 在通信结束后,客户端应该关闭 WebSocket 连接,释放资源。
环境安装与配置
Windows + Qt5
效果如下:
基于Qt的WebSocket客户端示例
// qt.pro
QT += websockets
// websocketclient.h
#ifndef WEBSOCKETCLIENT_H
#define WEBSOCKETCLIENT_H
#include <QObject>
#include <QtWebSockets>
#include <QDebug>
#include <QUrl>
class WebSocketClient : public QObject
{
Q_OBJECT
public:
explicit WebSocketClient(QObject *parent = nullptr);
~WebSocketClient();
void connectUrl(QString url); // 连接websocket服务器的URL
void close(); // 关闭websocket
void sendTextMsg(const QString &message); // 发送Text类型的消息
void sendBinaryMsg(const QByteArray &data); // 发送Binary类型的消息
bool getConStatus(); // 返回服务器连接状态
signals:
void sigRecvTextMsg(QString message); // 接受到Text类型消息的信号
private slots:
void slotConnected(); // 连接成功
void slotDisconnected(); // 断开连接
void slotRecvTextMsg(QString message); // 接受字符数据
void slotRecvBinaryMsg(QByteArray message); // 接受二进制数据
void slotError(QAbstractSocket::SocketError error); // 响应报错
private:
void reconnect(); // 断开重连
QWebSocket *m_pWebSocket;
QUrl m_url;
bool m_bConnected = false; // 为true,表明已连接服务器,否则未连接上
};
#endif // WEBSOCKETCLIENT_H
// websocketclient.cpp
#include "websocketclient.h"
WebSocketClient::WebSocketClient(QObject *parent) : QObject(parent)
{
m_pWebSocket = new QWebSocket();
// 连接相应的信号槽
connect(m_pWebSocket, SIGNAL(connected()), this, SLOT(slotConnected()));
connect(m_pWebSocket, SIGNAL(disconnected()), this, SLOT(slotDisconnected()));
connect(m_pWebSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotError(QAbstractSocket::SocketError)));
}
WebSocketClient::~WebSocketClient()
{
if(m_pWebSocket != 0)
{
m_pWebSocket->deleteLater();
m_pWebSocket = 0;
}
}
// 连接websocket服务器的URL
void WebSocketClient::connectUrl(QString url)
{
m_url = QUrl(url);
m_pWebSocket->open(m_url);
}
// 关闭websocket
void WebSocketClient::close()
{
m_pWebSocket->close();
}
// 发送Text类型的消息
void WebSocketClient::sendTextMsg(const QString &message)
{
if(!m_bConnected)
{
qDebug() << __FILE__ << __LINE__ << "Failed to" << __FUNCTION__ << ", it's not running...";
return;
}
//qDebug() << "send: " << message;
m_pWebSocket->sendTextMessage(message);
}
// 发送Binary类型的消息
void WebSocketClient::sendBinaryMsg(const QByteArray &data)
{
if(!m_bConnected)
{
qDebug() << __FILE__ << __LINE__ << "Failed to" << __FUNCTION__ << ", it's not running...";
return;
}
m_pWebSocket->sendBinaryMessage(data);
}
// 返回服务器连接状态
bool WebSocketClient::getConStatus()
{
return m_bConnected;
}
// 连接成功
void WebSocketClient::slotConnected()
{
qDebug()<<"connect successful";
m_bConnected = true;
connect(m_pWebSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(slotRecvTextMsg(QString)));
connect(m_pWebSocket, SIGNAL(binaryMessageReceived(QByteArray)), this, SLOT(slotRecvBinaryMsg(QByteArray)));
}
// 断开连接
void WebSocketClient::slotDisconnected()
{
qDebug() << __FILE__ << __LINE__ << "disconnected";
reconnect();
}
// 接受字符数据
void WebSocketClient::slotRecvTextMsg(QString message)
{
emit sigRecvTextMsg(message);
}
// 接受二进制数据
void WebSocketClient::slotRecvBinaryMsg(QByteArray message)
{
qDebug() << "slotRecvBinaryMsg: " << message;
}
// 响应报错
void WebSocketClient::slotError(QAbstractSocket::SocketError error)
{
qDebug() << __FILE__ << __LINE__ << (int)error << m_pWebSocket->errorString();
}
// 断开重连
void WebSocketClient::reconnect()
{
qDebug() << "websocket reconnected";
m_pWebSocket->abort();
m_pWebSocket->open(m_url);
}
// widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QListWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMessageBox>
#include "websocketclient.h"
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void slotSendMsg(); // 发送消息的槽函数
void slotRecvTextMsg(QString sMessage); // 接受WebSocketClient传来的文本消息
private:
QListWidget *listwidget;
QLineEdit *lineedit;
WebSocketClient *m_pWebSocketClinet; // WebSocket客户端
};
#endif // WIDGET_H
// widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent)
{
this->setWindowTitle("WebSocket客户端");
// 初始化窗口部件
listwidget = new QListWidget;
lineedit = new QLineEdit;
QPushButton *sendbutton = new QPushButton("发 送");
QPushButton *cancelbutton = new QPushButton("取 消");
this->connect(sendbutton, SIGNAL(clicked()), this, SLOT(slotSendMsg()));
this->connect(cancelbutton, SIGNAL(clicked()), this,SLOT(close()));
// 布局
QHBoxLayout * hlayout = new QHBoxLayout;
hlayout->addStretch(0);
hlayout->addWidget(sendbutton);
hlayout->addWidget(cancelbutton);
QVBoxLayout *vlayout = new QVBoxLayout(this);
vlayout->addWidget(listwidget);
vlayout->addWidget(lineedit);
vlayout->addLayout(hlayout);
// 初始化服务器
m_pWebSocketClinet = new WebSocketClient;
m_pWebSocketClinet->connectUrl("ws://localhost:8080");
connect(m_pWebSocketClinet, SIGNAL(sigRecvTextMsg(QString)), this, SLOT(slotRecvTextMsg(QString)));
}
Widget::~Widget()
{
}
// 发送消息的槽函数
void Widget::slotSendMsg()
{
QString content = lineedit->text(); //获取单行文本框内要发送的内容
if(!content.isEmpty())
{
QDateTime datetime = QDateTime::currentDateTime();
QString str = "send to server : " + datetime.toString("yyyy-M-dd hh:mm:ss") + tr("\n");
str += content;
listwidget->addItem(str); // 将要发送的内容显示在listwidget
m_pWebSocketClinet->sendTextMsg(str); // 发送消息到服务器
}
else
{
QMessageBox::critical(this, "错误", "不能发送空消息!", QMessageBox::Ok);
}
lineedit->clear();
}
// 接受WebSocketClient传来的文本消息
void Widget::slotRecvTextMsg(QString sMessage)
{
// 加上时间帧
QDateTime datetime = QDateTime::currentDateTime();
QString str = tr("recv from server : ") + datetime.toString("yyyy-M-dd hh:mm:ss") + tr("\n");
str += sMessage;
listwidget->addItem(str); // 将接收到的内容加入到listwidget
}
热门推荐
揭秘古代皇后的真实权力:从政治合伙人到皇家打工人
使用RVC变声器时需要注意什么?
波立维与阿司匹林:抗血小板药物的副作用对比
从预防到预测:自动化设备维护策略与实践指南
手动到电动:四种主要铆接工艺详解
数字化扭力检测仪:精准控制螺栓预紧力的工业利器
轨道列车螺栓预紧力计算:四大因素影响安全运行
徽州千年宗谱入选世界记忆名录,展现中华谱牒文化
现代农业科技的核心驱动力——揭秘智能技术如何改变农田面貌
250亿斤!“冰城粮”给粮食安全“压舱石”添分量
高标准农田信息化解决方案:让每一寸土地都发挥最大价值
设施农业+高附加值农产品,会碰撞出什么火花
白帝城瞿塘峡:三国古迹与长江奇观的完美融合
瞿塘峡:天下雄关里的自然与人文交响
三峡之巅瞿塘峡一日游,你去过吗?
李元芳担任的“千牛卫大将军”在唐朝的官职解析
狄仁杰系列八大高手排名:李元芳、元齐、虺文忠谁最强?
脑梗患者营养食谱大公开
新股交易规则大揭秘:主板VS科创板
A股新股上市首周无涨跌停限制,你准备好了吗?
北交所新股上市规则大变,你准备好了吗?
三国志11:从游戏设定的角度来看,周瑜和诸葛亮到底谁更胜一筹?
慢阻肺患者的饮食指南:哪些该吃哪些该忌
扩香石:环保香薰的使用指南及6款创意产品推荐
保肝护胆有良方:熊胆粉功效与人工替代技术
从活熊取胆到人工合成:熊胆粉产业的转型之路
熊胆粉功效与使用全解析:人工合成破解动物保护难题
世界经济论坛:2024年全球性别差距报告
上海城隍庙:一座庙宇见证的城市千年变迁
苏州河畔:自然人文交融的城市生态长廊