提交原始齿轮泵代码

This commit is contained in:
kite_lucs
2026-08-26 16:13:59 +08:00
commit afc8fcf2a4
1688 changed files with 316635 additions and 0 deletions
+186
View File
@@ -0,0 +1,186 @@
#include "message.h"
Message::Message(QObject *parent)
{
FRAME_START = 0x2B; // '+'
FRAME_END = 0x3C; // '<'
HEADER_SIZE = 4; // 1(起始) + 2(长度) + 1(预留)
TRAILER_SIZE = 1; // 1(结束)
MIN_FRAME_SIZE = HEADER_SIZE + TRAILER_SIZE; // 5字节
}
Message::~Message()
{
}
QByteArray Message::pack(const QByteArray &data)
{
// 检查数据长度
if (data.size() > 65535) {
//Message::pack - 数据长度超过65535字节限制
return QByteArray();
}
// 创建协议头
MsgHead head;
head.start = FRAME_START;
head.reserved = 0;
// 只保存实际内容的长度
head.length = static_cast<quint16>(data.size());
// head.toNetworkOrder(); // 转换为大端序
// 创建协议尾
MsgTail tail;
tail.end = FRAME_END;
// 构建完整帧
QByteArray frame;
frame.reserve(HEADER_SIZE + data.size() + TRAILER_SIZE);
// 添加头部
frame.append(reinterpret_cast<const char*>(&head), HEADER_SIZE);
// 添加数据
if (!data.isEmpty()) {
frame.append(data);
}
// 添加尾部
frame.append(reinterpret_cast<const char*>(&tail), TRAILER_SIZE);
return frame;
}
bool Message::unpack(const QByteArray &frame, QByteArray &data)
{
if (!validate(frame)) {
return false;
}
// 检查数据长度
MsgHead head;
memcpy(&head, frame.constData(), HEADER_SIZE);
quint16 dataLength = head.length;
int expectedSize = HEADER_SIZE + dataLength + TRAILER_SIZE;
if (frame.size() < expectedSize) {
// 帧不完整
return false;
}
// 提取数据
data = frame.mid(HEADER_SIZE, dataLength);
return true;
}
bool Message::validate(const QByteArray &frame)
{
// 检查最小长度
if (frame.size() < MIN_FRAME_SIZE) {
return false;
}
// 读取头部
MsgHead head;
memcpy(&head, frame.constData(), HEADER_SIZE);
// 验证起始标识
if (!head.isValid()) {
return false;
}
quint16 dataLength = head.length;
// 读取尾部
MsgTail tail;
memcpy(&tail, frame.constData() + HEADER_SIZE + dataLength, TRAILER_SIZE);
// 验证结束标识
if (!tail.isValid()) {
return false;
}
return true;
}
QByteArray Message::extractFrame(const QByteArray &buffer, int &consumedBytes)
{
consumedBytes = 0;
// 查找起始标识
int startPos = buffer.indexOf(FRAME_START);
if (startPos < 0) {
return QByteArray(); // 没有找到起始标识
}
// 检查是否有完整的头部
if (startPos + HEADER_SIZE > buffer.size()) {
return QByteArray(); // 头部不完整
}
// 读取数据长度
quint16 dataLength = readLength(buffer.mid(startPos, HEADER_SIZE));
// 计算完整帧大小
int frameSize = HEADER_SIZE + dataLength + TRAILER_SIZE;
// 检查是否有完整的帧
if (startPos + frameSize > buffer.size()) {
return QByteArray(); // 帧不完整
}
// 提取并验证完整帧
QByteArray frame = buffer.mid(startPos, frameSize);
if (!checkFrameBoundary(frame)) {
// 起始标识正确,但结束标识不正确,可能是错误的数据
// qWarning() << "Message::extractFrame - 帧边界检查失败";
consumedBytes = startPos + 1; // 跳过这个错误的起始标识
return QByteArray();
}
consumedBytes = startPos + frameSize;
return frame;
}
// 读取数据长度
quint16 Message::readLength(const QByteArray &frame)
{
if (frame.size() < HEADER_SIZE) {
return 0;
}
MsgHead head;
memcpy(&head, frame.constData(), HEADER_SIZE);
return head.length;
}
// 检查帧边界
bool Message::checkFrameBoundary(const QByteArray &frame)
{
if (frame.size() < MIN_FRAME_SIZE) {
return false;
}
// 检查起始标识
MsgHead head;
memcpy(&head, frame.constData(), HEADER_SIZE);
if (!head.isValid()) {
return false;
}
// 检查结束标识
int dataLength = head.length;
if (frame.size() < HEADER_SIZE + dataLength + TRAILER_SIZE) {
return false;
}
MsgTail tail;
memcpy(&tail, frame.constData() + HEADER_SIZE + dataLength, TRAILER_SIZE);
return tail.isValid();
}
+78
View File
@@ -0,0 +1,78 @@
#ifndef MESSAGE_H
#define MESSAGE_H
// 协议类:用于接收外部 网络通信 发送的打印内容
#include <QObject>
#include <QByteArray>
/*
| 起始标识(1B) | 预留字段(1B) | 内容长度(2B) | 数据内容(NB) | 结束标识(1B) |
| 0x2B | 自定义 | N() | 实际数据 | 0x3C |
2B 00 02 00 08 08 3C
*/
// 内存对齐
#pragma pack(push, 1)
struct MsgHead {
char start;
char reserved;
unsigned short length;
MsgHead() {
start = 0x2B;
reserved = 0;
length = 0;
}
bool isValid() {
return start == 0x2B;
}
};
struct MsgTail {
quint8 end;
MsgTail() {
end = 0x3C;
}
bool isValid() {
return end == 0x3C;
}
};
#pragma pack(pop)
class Message : public QObject
{
Q_OBJECT
public:
Message(QObject *parent = 0);
~Message();
// 打包:数据 + 预留字段 -> 完整帧
QByteArray pack(const QByteArray &data);
// 解包:完整帧 -> 数据和预留字段
bool unpack(const QByteArray &frame, QByteArray &data);
// 验证帧格式
bool validate(const QByteArray &frame);
QByteArray extractFrame(const QByteArray &buffer, int &consumedBytes);
private:
// 协议常量
char FRAME_START ; // '+' 0x2b
char FRAME_END; // '<' 0x3c
int HEADER_SIZE ; // 1(起始) + 2(长度) + 1(预留)
int TRAILER_SIZE; // 1(结束)
int MIN_FRAME_SIZE; // 5字节
quint16 readLength(const QByteArray &frame);
bool checkFrameBoundary(const QByteArray &frame);
};
#endif // MESSAGE_H
+156
View File
@@ -0,0 +1,156 @@
#include "serverthread.h"
#include <QDebug>
#include <QDateTime>
#include <QStringList>
ServerThread::ServerThread(QObject *parent)
: QThread(parent)
, m_running(false)
, m_processedCount(0)
, m_totalProcessedBytes(0)
{
qDebug() << "ServerThread 创建 - 线程ID:" << QThread::currentThreadId();
}
ServerThread::~ServerThread()
{
stopThread();
qDebug() << "ServerThread 销毁 - 处理任务数:" << m_processedCount;
}
void ServerThread::stopThread()
{
qDebug() << "ServerThread 停止中...";
m_running = false;
m_condition.wakeAll();
if (isRunning()) {
wait(5000); // 等待最多5秒
if (isRunning()) {
qWarning() << "ServerThread 强制终止";
terminate();
wait();
}
}
}
void ServerThread::addTask(const WorkTask &task)
{
QMutexLocker locker(&m_mutex);
m_taskQueue.enqueue(task);
m_condition.wakeOne();
}
int ServerThread::pendingTasks() const
{
QMutexLocker locker(&m_mutex);
return m_taskQueue.size();
}
quint64 ServerThread::processedCount() const
{
return m_processedCount;
}
quint64 ServerThread::totalProcessedBytes() const
{
return m_totalProcessedBytes;
}
bool ServerThread::isProcessing() const
{
QMutexLocker locker(&m_mutex);
return !m_taskQueue.isEmpty();
}
void ServerThread::run()
{
m_running = true;
while (m_running) {
WorkTask task;
bool hasTask = false;
{
QMutexLocker locker(&m_mutex);
if (m_taskQueue.isEmpty()) {
// 等待新任务,超时1秒后继续循环检查m_running
m_condition.wait(&m_mutex, 1000);
continue;
}
task = m_taskQueue.dequeue();
hasTask = true;
}
if (!hasTask || !m_running) {
continue;
}
// 处理任务
try {
QByteArray result;
switch (task.taskType) {
case 0: // 处理接收到的数据
result = processReceivedData(task.data);
break;
case 1: // 打包待发送数据
result = packSendData(task.data);
break;
default:
emit sig_taskError(task.socketId, QString("未知任务类型: %1").arg(task.taskType));
continue;
}
// 更新统计
m_processedCount++;
m_totalProcessedBytes += task.data.size();
// 发送处理结果
if (!result.isEmpty()) {
emit sig_taskProcessed(task.socketId, result);
}
} catch (const std::exception &e) {
emit sig_taskError(task.socketId, QString("处理异常: %1").arg(e.what()));
} catch (...) {
emit sig_taskError(task.socketId, "未知处理异常");
}
// 短暂休眠,避免CPU占用过高
msleep(1);
}
}
QByteArray ServerThread::processReceivedData(const QByteArray &data)
{
QString text = QString::fromUtf8(data);
// 普通数据处理示例
QByteArray result;
// 添加时间戳前缀
QString timestamp = QDateTime::currentDateTime().toString("[hh:mm:ss] ");
result = timestamp.toUtf8();
// 回显处理后的数据
result += text.toUtf8();
// 可以在此添加更多业务逻辑
// 例如:数据验证、转换、存储等
return result;
}
QByteArray ServerThread::packSendData(const QByteArray &data)
{
// 添加到待发送队列或进行预处理
// 这里简单返回原数据,实际打包在TcpServer中完成
return data;
}
+63
View File
@@ -0,0 +1,63 @@
#ifndef SERVER_THREAD_H
#define SERVER_THREAD_H
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QQueue>
#include <QByteArray>
// 工作任务结构体
struct WorkTask {
quint64 socketId;
QByteArray data;
int taskType; // 0: 处理数据, 1: 发送数据
WorkTask() : socketId(0), taskType(0) {}
WorkTask(quint64 id, const QByteArray &d, int type = 0)
: socketId(id), data(d), taskType(type) {}
};
class ServerThread : public QThread
{
Q_OBJECT
public:
explicit ServerThread(QObject *parent = 0);
~ServerThread();
// 线程控制
void stopThread();
void addTask(const WorkTask &task);
// 状态查询
int pendingTasks() const;
quint64 processedCount() const;
quint64 totalProcessedBytes() const;
bool isProcessing() const;
signals:
// 处理结果信号
void sig_taskProcessed(quint64 socketId, const QByteArray &processedData);
void sig_taskError(quint64 socketId, const QString &error);
protected:
void run() override;
private:
// 核心处理函数
QByteArray processReceivedData(const QByteArray &data);
QByteArray packSendData(const QByteArray &data);
// 线程控制
volatile bool m_running;
mutable QMutex m_mutex;
QWaitCondition m_condition;
QQueue<WorkTask> m_taskQueue;
// 统计信息
quint64 m_processedCount;
quint64 m_totalProcessedBytes;
};
#endif // SERVER_THREAD_H
+551
View File
@@ -0,0 +1,551 @@
#include "tcpserver.h"
#include <QDebug>
#include <QDateTime>
#include <QHostAddress>
#include "LogInfo.h"
// Qt4兼容的时间戳函数
qint64 TcpServer::getCurrentTimestamp() const
{
return QDateTime::currentDateTime().toTime_t();
}
QString TcpServer::getPeerAddress(QTcpSocket *socket) const
{
if (!socket) return QString();
return socket->peerAddress().toString();
}
quint16 TcpServer::getPeerPort(QTcpSocket *socket) const
{
if (!socket) return 0;
return socket->peerPort();
}
TcpServer::TcpServer(QObject *parent)
: QObject(parent)
, m_server(new QTcpServer(this))
, m_message(this)
, m_nextThreadIndex(0)
, m_maxPendingConnections(10) //最大连接数量
, m_maxBufferSize(1024 * 1024)
, m_heartbeatInterval(30)
, m_connectionTimeout(300)
, m_workerThreadCount(2) //工作线程数量
, m_nextSocketId(1)
, m_totalReceived(0)
, m_totalSent(0)
{
// 创建心跳定时器
m_heartbeatTimer = new QTimer(this);
connect(m_heartbeatTimer, SIGNAL(timeout()), this, SLOT(slt_onHeartbeatCheck()));
// 连接服务器信号
connect(m_server, SIGNAL(newConnection()), this, SLOT(slt_onNewConnection()));
// 创建工作线程
setWorkerThreadCount(m_workerThreadCount);
}
TcpServer::~TcpServer()
{
stop();
// 停止所有ServerThread
for (int i = 0; i < m_workerThreads.size(); ++i) {
m_workerThreads[i]->stopThread();
m_workerThreads[i]->deleteLater();
}
m_workerThreads.clear();
}
// 设置工作线程数量
void TcpServer::setWorkerThreadCount(int count)
{
if (count < 1) count = 1;
if (count > 8) count = 8;
// 停止现有线程
for (int i = 0; i < m_workerThreads.size(); ++i) {
m_workerThreads[i]->stopThread();
m_workerThreads[i]->deleteLater();
}
m_workerThreads.clear();
// 创建新的ServerThread
for (int i = 0; i < count; ++i) {
ServerThread *thread = new ServerThread(this);
// 连接ServerThread信号
connect(thread, SIGNAL(taskProcessed(quint64, const QByteArray&)),
this, SLOT(slt_onTaskProcessed(quint64, const QByteArray&)));
connect(thread, SIGNAL(taskError(quint64, const QString&)),
this, SLOT(slt_onTaskError(quint64, const QString&)));
connect(thread, SIGNAL(threadStatus(const QString&)),
this, SIGNAL(sig_logMessage(const QString&)));
m_workerThreads.append(thread);
thread->start();
emit sig_logMessage(QString("ServerThread %1 已启动").arg(i + 1));
}
m_workerThreadCount = count;
m_nextThreadIndex = 0;
}
int TcpServer::workerThreadCount() const
{
return m_workerThreadCount;
}
// 获取下一个ServerThread(轮询负载均衡)
ServerThread* TcpServer::getNextWorkerThread()
{
if (m_workerThreads.isEmpty()) {
return 0;
}
ServerThread *thread = m_workerThreads[m_nextThreadIndex];
m_nextThreadIndex = (m_nextThreadIndex + 1) % m_workerThreads.size();
return thread;
}
// 分发任务到ServerThread
void TcpServer::distributeToWorkerThread(quint64 socketId, const QByteArray &data, int taskType)
{
ServerThread *thread = getNextWorkerThread();
if (thread) {
WorkTask task(socketId, data, taskType);
thread->addTask(task);
}
}
// ServerThread处理完成回调
void TcpServer::slt_onTaskProcessed(quint64 socketId, const QByteArray &processedData)
{
if (!validateSocket(socketId)) {
emit sig_logMessage(QString("处理完成但客户端 %1 已断开").arg(socketId), 1);
return;
}
// 打包并发送处理后的数据
QByteArray frame = m_message.pack(processedData);
if (!frame.isEmpty()) {
QTcpSocket *socket = m_clientMap[socketId];
socket->write(frame);
m_totalSent += frame.size();
if (m_clientInfoMap.contains(socketId)) {
m_clientInfoMap[socketId].totalSent += frame.size();
}
}
}
// ServerThread错误回调
void TcpServer::slt_onTaskError(quint64 socketId, const QString &error)
{
emit sig_logMessage(QString("ServerThread处理错误 - SocketID:%1, 错误:%2").arg(socketId).arg(error), 2);
}
// 启动服务器
bool TcpServer::start(quint16 port, const QHostAddress &address)
{
if (m_server->isListening()) {
emit sig_logMessage("服务器已经在运行中");
return true;
}
m_server->setMaxPendingConnections(m_maxPendingConnections);
if (!m_server->listen(address, port)) {
QString error = QString("服务器启动失败: %1").arg(m_server->errorString());
emit sig_serverError(error);
emit sig_logMessage(error, 2);
return false;
}
if (m_heartbeatInterval > 0) {
m_heartbeatTimer->start(m_heartbeatInterval * 1000);
}
emit sig_serverStarted(m_server->serverPort());
emit sig_logMessage(QString("服务器启动成功 - 端口:%1, ServerThread数:%2")
.arg(m_server->serverPort())
.arg(m_workerThreadCount));
return true;
}
// 停止服务器
void TcpServer::stop()
{
// 1. 停止心跳定时器
if (m_heartbeatTimer->isActive()) {
m_heartbeatTimer->stop();
}
// 2. 停止接受新连接
m_server->close();
// 3. 断开所有客户端连接
QList<quint64> clientIds = m_clientMap.keys();
for (int i = 0; i < clientIds.size(); ++i) {
cleanupClient(clientIds[i], "服务器关闭");
}
// 4. 停止所有工作线程
for (int i = 0; i < m_workerThreads.size(); ++i) {
if (m_workerThreads[i]->isRunning()) {
m_workerThreads[i]->stopThread();
m_workerThreads[i]->wait(5000); // 等待线程退出
}
}
// 5. 清空所有数据结构
m_clientMap.clear();
m_clientInfoMap.clear();
emit sig_serverStopped();
emit sig_logMessage("服务器已停止");
}
bool TcpServer::isRunning() const
{
return m_server->isListening();
}
// 发送数据到客户端
bool TcpServer::sendToClient(quint64 socketId, const QByteArray &data)
{
if (!validateSocket(socketId)) {
emit sig_logMessage(QString("发送失败: 客户端 %1 不存在").arg(socketId), 1);
return false;
}
// 通过ServerThread打包发送
// 就目前项目而言,应该用不到多线程处理
// distributeToWorkerThread(socketId, data, 1);
return true;
}
bool TcpServer::sendToAll(const QByteArray &data)
{
bool success = true;
QList<quint64> clientIds = m_clientMap.keys();
for (int i = 0; i < clientIds.size(); ++i) {
if (!sendToClient(clientIds[i], data)) {
success = false;
}
}
return success;
}
bool TcpServer::sendToAllExcept(quint64 socketId, const QByteArray &data)
{
bool success = true;
QList<quint64> clientIds = m_clientMap.keys();
for (int i = 0; i < clientIds.size(); ++i) {
if (clientIds[i] != socketId) {
if (!sendToClient(clientIds[i], data)) {
success = false;
}
}
}
return success;
}
// 新连接处理
void TcpServer::slt_onNewConnection()
{
while (m_server->hasPendingConnections()) {
QTcpSocket *socket = m_server->nextPendingConnection();
if (!socket) continue;
quint64 socketId = m_nextSocketId++;
setupSocket(socket);
ClientInfo info;
info.address = getPeerAddress(socket);
info.port = getPeerPort(socket);
info.socketId = socketId;
info.lastActiveTime = getCurrentTimestamp();
m_clientMap[socketId] = socket;
m_clientInfoMap[socketId] = info;
emit sig_clientConnected(socketId, info.address, info.port);
emit sig_logMessage(QString("新客户端连接 %1 - %2:%3")
.arg(socketId)
.arg(info.address)
.arg(info.port));
emitStatistics();
}
}
// 数据接收处理
void TcpServer::slt_onReadyRead()
{
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) return;
LogInfo::setRunStatusText("TCPServer onReadyRead");
// 查找SocketId
quint64 socketId = 0;
QHash<quint64, QTcpSocket*>::const_iterator it;
for (it = m_clientMap.constBegin(); it != m_clientMap.constEnd(); ++it) {
if (it.value() == socket) {
socketId = it.key();
break;
}
}
if (socketId == 0) {
emit sig_logMessage("接收到未知Socket的数据", 1);
return;
}
QByteArray newData = socket->readAll();
m_totalReceived += newData.size();
if (m_clientInfoMap.contains(socketId)) {
m_clientInfoMap[socketId].totalReceived += newData.size();
m_clientInfoMap[socketId].lastActiveTime = getCurrentTimestamp();
}
emit sig_rawDataReceived(socketId, newData);
if (!m_clientInfoMap.contains(socketId)) return;
QByteArray &buffer = m_clientInfoMap[socketId].buffer;
buffer.append(newData);
if (buffer.size() > m_maxBufferSize) {
emit sig_logMessage(QString("客户端 %1 缓冲区溢出").arg(socketId), 2);
cleanupClient(socketId, "缓冲区溢出");
return;
}
processBuffer(socketId);
}
// 处理接收缓冲区
void TcpServer::processBuffer(quint64 socketId)
{
if (!m_clientInfoMap.contains(socketId)) return;
QByteArray &buffer = m_clientInfoMap[socketId].buffer;
int totalConsumed = 0;
while (totalConsumed < buffer.size()) {
QByteArray remainingBuffer = buffer.mid(totalConsumed);
int consumed = 0;
QByteArray frame = m_message.extractFrame(remainingBuffer, consumed);
if (frame.isEmpty()) {
if (consumed > 0) {
totalConsumed += consumed;
continue;
}
break;
}
QByteArray data;
if (m_message.unpack(frame, data)) {
emit sig_dataReceived(socketId, data);
// 分发到ServerThread处理
// 就目前项目而言,应该用不到多线程处理
// distributeToWorkerThread(socketId, data, 0);
} else {
LogInfo::setRunStatusText("processBuffer:解包失败");
emit sig_logMessage(QString("客户端 %1 解包失败").arg(socketId), 1);
}
totalConsumed += consumed;
}
if (totalConsumed > 0) {
buffer.remove(0, totalConsumed);
}
}
// 客户端断开
void TcpServer::slt_onDisconnected()
{
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) return;
quint64 socketId = 0;
QHash<quint64, QTcpSocket*>::iterator it;
for (it = m_clientMap.begin(); it != m_clientMap.end(); ++it) {
if (it.value() == socket) {
socketId = it.key();
break;
}
}
if (socketId == 0) return;
cleanupClient(socketId, "客户端主动断开");
}
void TcpServer::slt_onSocketError(QAbstractSocket::SocketError socketError)
{
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) return;
quint64 socketId = 0;
QHash<quint64, QTcpSocket*>::const_iterator it;
for (it = m_clientMap.constBegin(); it != m_clientMap.constEnd(); ++it) {
if (it.value() == socket) {
socketId = it.key();
break;
}
}
if (socketId == 0) return;
QString errorMsg = socket->errorString();
emit sig_clientError(socketId, errorMsg);
emit sig_logMessage(QString("客户端 %1 错误: %2").arg(socketId).arg(errorMsg), 2);
if (socketError != QAbstractSocket::RemoteHostClosedError) {
cleanupClient(socketId, "Socket错误: " + errorMsg);
}
}
void TcpServer::slt_onHeartbeatCheck()
{
qint64 currentTime = getCurrentTimestamp();
QList<quint64> timeoutClients;
QHash<quint64, ClientInfo>::iterator it;
for (it = m_clientInfoMap.begin(); it != m_clientInfoMap.end(); ++it) {
if (currentTime - it.value().lastActiveTime > m_connectionTimeout) {
timeoutClients.append(it.key());
}
}
for (int i = 0; i < timeoutClients.size(); ++i) {
cleanupClient(timeoutClients[i], "连接超时");
}
if (!timeoutClients.isEmpty()) {
emitStatistics();
}
}
void TcpServer::setupSocket(QTcpSocket *socket)
{
socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
connect(socket, SIGNAL(readyRead()), this, SLOT(slt_onReadyRead()));
connect(socket, SIGNAL(disconnected()), this, SLOT(slt_onDisconnected()));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(slt_onSocketError(QAbstractSocket::SocketError)));
}
void TcpServer::cleanupClient(quint64 socketId, const QString &reason)
{
QTcpSocket *socket = m_clientMap.value(socketId);
if (!socket) return;
emit sig_clientDisconnected(socketId, reason);
emit sig_logMessage(QString("客户端 %1 断开: %2").arg(socketId).arg(reason));
m_clientMap.remove(socketId);
m_clientInfoMap.remove(socketId);
socket->disconnectFromHost();
if (socket->state() != QAbstractSocket::UnconnectedState) {
socket->waitForDisconnected(1000);
}
socket->deleteLater();
emitStatistics();
}
void TcpServer::updateClientActivity(quint64 socketId)
{
if (m_clientInfoMap.contains(socketId)) {
m_clientInfoMap[socketId].lastActiveTime = getCurrentTimestamp();
}
}
bool TcpServer::validateSocket(quint64 socketId)
{
if (!m_clientMap.contains(socketId)) return false;
QTcpSocket *socket = m_clientMap[socketId];
return socket && socket->state() == QAbstractSocket::ConnectedState;
}
void TcpServer::emitStatistics()
{
int activeThreads = 0;
for (int i = 0; i < m_workerThreads.size(); ++i) {
if (m_workerThreads[i]->isProcessing()) {
activeThreads++;
}
}
emit sig_statisticsUpdated(m_clientMap.size(), activeThreads,
m_totalReceived, m_totalSent);
}
quint16 TcpServer::serverPort() const
{
return m_server->serverPort();
}
int TcpServer::clientCount() const
{
return m_clientMap.size();
}
QList<ClientInfo> TcpServer::getClientList() const
{
return m_clientInfoMap.values();
}
ClientInfo TcpServer::getClientInfo(quint64 socketId) const
{
return m_clientInfoMap.value(socketId);
}
void TcpServer::setMaxPendingConnections(int maxConnections)
{
m_maxPendingConnections = maxConnections;
if (m_server->isListening()) {
m_server->setMaxPendingConnections(maxConnections);
}
}
void TcpServer::setMaxBufferSize(int maxSize)
{
m_maxBufferSize = maxSize;
}
void TcpServer::setHeartbeatInterval(int seconds)
{
m_heartbeatInterval = seconds;
if (m_heartbeatTimer->isActive()) {
m_heartbeatTimer->setInterval(seconds * 1000);
}
}
void TcpServer::setConnectionTimeout(int seconds)
{
m_connectionTimeout = seconds;
}
+147
View File
@@ -0,0 +1,147 @@
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHash>
#include <QTimer>
#include <QHostAddress>
#include <QDateTime>
#include <QList>
#include <QString>
#include <QThread>
#include "message.h"
#include "serverthread.h"
/**
TCP 服务端模块,用于处理外部tcp发来的数据
**/
// 客户端连接信息
struct ClientInfo {
QString address;
quint16 port;
quint64 socketId;
QByteArray buffer; // 接收缓冲区
qint64 lastActiveTime; // 最后活跃时间
quint64 totalReceived; // 总接收字节数
quint64 totalSent; // 总发送字节数
ClientInfo() {
port = 0;
socketId = 0;
lastActiveTime = 0;
totalReceived = 0;
totalSent = 0;
}
};
class TcpServer : public QObject
{
Q_OBJECT
public:
explicit TcpServer(QObject *parent = 0);
~TcpServer();
// 服务器控制
bool start(quint16 port, const QHostAddress &address = QHostAddress::Any);
void stop();
bool isRunning() const;
// 发送数据
bool sendToClient(quint64 socketId, const QByteArray &data);
bool sendToAll(const QByteArray &data);
bool sendToAllExcept(quint64 socketId, const QByteArray &data);
// 线程管理
void setWorkerThreadCount(int count);
int workerThreadCount() const;
// 获取服务器状态
quint16 serverPort() const;
int clientCount() const;
QList<ClientInfo> getClientList() const;
ClientInfo getClientInfo(quint64 socketId) const;
// 配置选项
void setMaxPendingConnections(int maxConnections);
void setMaxBufferSize(int maxSize);
void setHeartbeatInterval(int seconds);
void setConnectionTimeout(int seconds);
signals:
// 服务器状态信号
void sig_serverStarted(quint16 port);
void sig_serverStopped();
void sig_serverError(const QString &error);
// 客户端连接信号
void sig_clientConnected(quint64 socketId, const QString &address, quint16 port);
void sig_clientDisconnected(quint64 socketId, const QString &reason);
void sig_clientError(quint64 socketId, const QString &error);
// 数据接收信号
void sig_dataReceived(quint64 socketId, const QByteArray &data);
void sig_rawDataReceived(quint64 socketId, const QByteArray &rawData);
// 统计信号
void sig_statisticsUpdated(int clientCount, int threadCount,
quint64 totalReceived, quint64 totalSent);
// 日志信号
void sig_logMessage(const QString &message, int level = 0);
private slots:
void slt_onNewConnection();
void slt_onReadyRead();
void slt_onDisconnected();
void slt_onSocketError(QAbstractSocket::SocketError socketError);
void slt_onHeartbeatCheck();
void slt_onTaskProcessed(quint64 socketId, const QByteArray &processedData);
void slt_onTaskError(quint64 socketId, const QString &error);
private:
// 核心组件
QTcpServer *m_server;
QHash<quint64, QTcpSocket*> m_clientMap;
QHash<quint64, ClientInfo> m_clientInfoMap;
Message m_message;
// 工作线程池
QList<ServerThread*> m_workerThreads;
int m_nextThreadIndex;
// 配置参数
int m_maxPendingConnections; //最大连接数量
int m_maxBufferSize;
int m_heartbeatInterval; //心跳
int m_connectionTimeout;
int m_workerThreadCount; //工作线程数量
// 定时器
QTimer *m_heartbeatTimer;
// 统计信息
quint64 m_nextSocketId;
quint64 m_totalReceived;
quint64 m_totalSent;
// 内部方法
void setupSocket(QTcpSocket *socket);
void processBuffer(quint64 socketId);
void distributeToWorkerThread(quint64 socketId, const QByteArray &data, int taskType);
void cleanupClient(quint64 socketId, const QString &reason);
void updateClientActivity(quint64 socketId);
bool validateSocket(quint64 socketId);
void emitStatistics();
ServerThread* getNextWorkerThread();
// Qt4兼容的辅助方法
qint64 getCurrentTimestamp() const;
QString getPeerAddress(QTcpSocket *socket) const;
quint16 getPeerPort(QTcpSocket *socket) const;
};
#endif // TCPSERVER_H