Qt使用socket单端口监听多台设备策略
项目背景:客户端设备启动后便会一直向指定ip和端口下发送信息,每次发送的时间间隔1秒,发送的内容包括设备的配置内容。服务端要求编写代码,通过socket与多台客户端设备建立长连接,持续地获取客户端发送的消息,分别解析它们然后在前端显示。此外,服务端设备还需要可以选择设备定向发送命令,从而操控该设备。
项目环境:Linux系统 + Qt前、后端 + sqlite数据库
解决思路:因为需要连接到多台设备,因此需要使用多线程,每个子线程分别处理一台客户端设备发送的内容。每当服务端获取到客户端发来的连接请求时,就新建一个线程,并分配一个socket。创建完线程后,解析到信息并在数据库创建条目,保存客户端配置内容。
*我这里还在数据库建了一个socket 的id字段,因为发现新设备后,前端就会创建一个新的下拉栏,存在于下拉栏中的旧设备不做排序,但socket是按照连接顺序分配的,因此下拉栏的索引很可能与socket id不一致。因此socket id与解析到的主键相对应,服务端收到信息后先解析到主键,分配socket id。下拉栏按照主键的内容解析socket id,从而解决了匹配不一致的问题。
理清解决思路后,首先搞定socket连接的问题。在Qt中,首先要在.pro文件中添加:
QT += network
然后在代码中包含库:
#include <QTcpServer>
#include <QTcpSocket>
头文件中需要声明:
QTcpServer* server;
QTcpSocket* socket[MAX_CONNECTION];
int socketId = -1;
server只需要一个,但socket需要很多个。这里创建数组用来给连接进来的客户端分配socket id。
然后在构造函数里添加:
server = new QTcpServer();
connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);
void MainWindow::server_New_Connect()
{
socketId++;
int sid = socketId;
//每有一个新连接,就新建一个线程
QtConcurrent::run([=]()
{
//获取客户端连接
socket[socketId] = server->nextPendingConnection();
//连接QTcpSocket的信号槽,以读取新数据
QObject::connect(socket[sid], &QTcpSocket::readyRead, this, [=](){
socket_Read_Data(sid);});
QObject::connect(socket[sid], &QTcpSocket::disconnected, this, [=](){
socket_Disconnected(sid);});
qDebug() << "A Client connect!";
});
}
这里使用concurrent实际上是使用了并发,每当获取到新的连接时,相当于都开启了一个线程动态处理请求。获取到请求后socket id加1,然后将其分配给该连接,用信号槽关联到读取数据和断开连接函数。为了传递socket id参数,在信号槽里使用lambda。
读取数据和断开连接的slot如下:
void MainWindow::socket_Read_Data(int socketId)
{
QByteArray buffer;
//读取缓冲区数据
buffer = socket[socketId]->readAll();
if

本文介绍了如何使用Qt在Linux环境下,通过socket实现实时监听多台客户端设备,并通过多线程处理每个设备的连接。项目涉及数据库管理,确保与前端界面的同步,同时支持定向发送命令。文章详细阐述了网络连接、数据库操作及前端界面的实现策略,包括并发处理、数据库记录更新以及前端UI动态显示。
最低0.47元/天 解锁文章
2736

被折叠的 条评论
为什么被折叠?



