#include "BeltTearingPresenter.h" #include #include #include #include #include #include #include #include #include BeltTearingPresenter::BeltTearingPresenter(QObject *parent) : QObject(parent) , m_tcpServer(new QTcpServer(this)) , m_dataTimer(new QTimer(this)) , m_port(0) { // 连接信号槽 connect(m_tcpServer, &QTcpServer::newConnection, this, &BeltTearingPresenter::onNewConnection); connect(m_dataTimer, &QTimer::timeout, this, &BeltTearingPresenter::onSendSimulatedData); } BeltTearingPresenter::~BeltTearingPresenter() { stopServer(); } bool BeltTearingPresenter::startServer(quint16 port) { if (m_tcpServer->isListening()) { stopServer(); } m_port = port; bool result = m_tcpServer->listen(QHostAddress::Any, port); if (result) { std::cout << "TCP server started on port " << port << std::endl; } else { std::cout << "Failed to start TCP server: " << m_tcpServer->errorString().toStdString() << std::endl; } return result; } void BeltTearingPresenter::stopServer() { // 断开所有客户端连接 for (auto it = m_clients.begin(); it != m_clients.end(); ++it) { it.value()->disconnectFromHost(); } m_clients.clear(); // 停止服务器监听 if (m_tcpServer->isListening()) { m_tcpServer->close(); } // 停止数据发送定时器 stopSendingSimulatedData(); m_port = 0; } void BeltTearingPresenter::startSendingSimulatedData() { // 启动定时器,每2秒发送一次模拟数据 m_dataTimer->start(1000); } void BeltTearingPresenter::stopSendingSimulatedData() { if (m_dataTimer->isActive()) { m_dataTimer->stop(); } } void BeltTearingPresenter::onNewConnection() { while (m_tcpServer->hasPendingConnections()) { QTcpSocket *socket = m_tcpServer->nextPendingConnection(); // 生成客户端ID QString clientId = generateClientId(socket); // 存储客户端连接 m_clients[clientId] = socket; // 连接客户端信号 connect(socket, &QTcpSocket::disconnected, this, &BeltTearingPresenter::onClientDisconnected); std::cout << "Client connected: " << clientId.toStdString() << std::endl; // 发送欢迎消息 QByteArray welcomeMsg = "Welcome to BeltTearing Server!"; socket->write(welcomeMsg); } } void BeltTearingPresenter::onClientDisconnected() { QTcpSocket *socket = qobject_cast(sender()); if (!socket) { return; } // 查找断开连接的客户端ID QString clientId; for (auto it = m_clients.begin(); it != m_clients.end(); ++it) { if (it.value() == socket) { clientId = it.key(); break; } } if (!clientId.isEmpty()) { m_clients.remove(clientId); std::cout << "Client disconnected: " << clientId.toStdString() << std::endl; } socket->deleteLater(); } void BeltTearingPresenter::onSendSimulatedData() { // 向所有连接的客户端发送模拟数据 for (auto it = m_clients.begin(); it != m_clients.end(); ++it) { QTcpSocket *socket = it.value(); if (socket->state() == QAbstractSocket::ConnectedState) { // 随机选择发送图像或日志记录 sendSimulatedImage(socket); sendSimulatedLogRecords(socket); } } } void BeltTearingPresenter::sendSimulatedImage(QTcpSocket *socket) { // 创建一个模拟的图像 cv::Mat image(480, 640, CV_8UC3, cv::Scalar(128, 128, 128)); // 在图像上绘制一些随机内容 cv::circle(image, cv::Point(320, 240), 50, cv::Scalar(0, 0, 255), -1); cv::rectangle(image, cv::Rect(100, 100, 200, 150), cv::Scalar(0, 255, 0), 2); static unsigned int s_imageCount = 0; // 在图像上叠加数字 QString numberText = QString::number(++s_imageCount); // 生成一个随机数 cv::putText(image, numberText.toStdString(), cv::Point(50, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 255, 255), 2); // 编码图像 std::vector imgBuffer; std::vector params = {cv::IMWRITE_PNG_COMPRESSION, 3}; cv::imencode(".png", image, imgBuffer, params); QByteArray byteArray(reinterpret_cast(imgBuffer.data()), imgBuffer.size()); // 创建数据包 QByteArray package; QDataStream stream(&package, QIODevice::WriteOnly); stream.setByteOrder(QDataStream::BigEndian); stream << quint8(static_cast(ByteDataType::Image)) << quint32(byteArray.size()); package.append(byteArray); package.append("___END___\r\n"); // 发送数据 socket->write(package); std::cout << "Sent simulated image data to client" << std::endl; } void BeltTearingPresenter::sendSimulatedLogRecords(QTcpSocket *socket) { // 创建模拟日志记录 QJsonArray logRecords; for (int i = 0; i < 3; i++) { QJsonObject record; record["timestamp"] = QDateTime::currentDateTime().toString(Qt::ISODate); record["level"] = QString("INFO"); record["message"] = QString("Simulated log message %1").arg(i + 1); record["source"] = QString("BeltTearingDetector"); logRecords.append(record); } // 将日志记录转换为JSON字符串 QJsonDocument doc(logRecords); QByteArray message = doc.toJson(QJsonDocument::Compact); // 创建数据包 QByteArray package; QDataStream stream(&package, QIODevice::WriteOnly); stream.setByteOrder(QDataStream::BigEndian); stream << quint8(static_cast(ByteDataType::Text)) << quint32(message.size()); package.append(message); package.append("___END___\r\n"); // 发送数据 socket->write(package); std::cout << "Sent simulated log records to client" << std::endl; } QString BeltTearingPresenter::generateClientId(QTcpSocket *socket) { // 使用UUID生成唯一的客户端ID return QUuid::createUuid().toString(); }