开源 C++ QT QML 开发(十七)进程--LocalSocket

文章的目的为了记录使用QT QML开发学习的经历。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

相关链接:

开源 C++ QT QML 开发(一)基本介绍

开源 C++ QT QML 开发(二)工程结构

开源 C++ QT QML 开发(三)常用控件

开源 C++ QT QML 开发(四)复杂控件--Listview

开源 C++ QT QML 开发(五)复杂控件--Gridview

开源 C++ QT QML 开发(六)自定义控件--波形图

开源 C++ QT QML 开发(七)自定义控件--仪表盘

开源 C++ QT QML 开发(八)自定义控件--圆环

开源 C++ QT QML 开发(九)文件--文本和二进制

开源 C++ QT QML 开发(十)通讯--串口

开源 C++ QT QML 开发(十一)通讯--TCP服务器端

开源 C++ QT QML 开发(十二)通讯--TCP客户端

开源 C++ QT QML 开发(十三)多线程

开源 C++ QT QML 开发(十四)进程用途

开源 C++ QT QML 开发(十五)通讯--http下载

开源 C++ QT QML 开发(十六)进程--共享内存

开源 C++ QT QML 开发(十七)进程--LocalSocket

开源 C++ QT QML 开发(十八)多媒体--音频播放

推荐链接:

开源 C# 快速开发(一)基础知识

开源 C# 快速开发(二)基础控件

开源 C# 快速开发(三)复杂控件

开源 C# 快速开发(四)自定义控件--波形图

开源 C# 快速开发(五)自定义控件--仪表盘

开源 C# 快速开发(六)自定义控件--圆环

开源 C# 快速开发(七)通讯--串口

开源 C# 快速开发(八)通讯--Tcp服务器端

开源 C# 快速开发(九)通讯--Tcp客户端

开源 C# 快速开发(十)通讯--http客户端

开源 C# 快速开发(十一)线程

开源 C# 快速开发(十二)进程监控

开源 C# 快速开发(十三)进程--管道通讯

开源 C# 快速开发(十四)进程--内存映射

开源 C# 快速开发(十五)进程--windows消息

开源 C# 快速开发(十六)数据库--sqlserver增删改查

本章节主要内容是:进程之间通讯, Qt Local Socket 的客户端-服务器通信系统。

本地套接字(Unix Domain Socket)在QT中通过QLocalSocket和QLocalServer类实现,用于同一台机器上的进程间通信(IPC)。

1.代码分析

2.所有源码

3.效果演示

一、代码分析LocalSocketClient 类详细分析

构造函数

复制代码
LocalSocketClient::LocalSocketClient(QObject *parent) : QObject(parent)
{
    m_socket = new QLocalSocket(this);
    
    // 连接信号槽
    connect(m_socket, &QLocalSocket::connected, this, &LocalSocketClient::onConnected);
    connect(m_socket, &QLocalSocket::disconnected, this, &LocalSocketClient::onDisconnected);
    connect(m_socket, &QLocalSocket::readyRead, this, &LocalSocketClient::readData);
    connect(m_socket, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error),
            this, &LocalSocketClient::onError);

    // 自动重连定时器
    m_reconnectTimer = new QTimer(this);
    m_reconnectTimer->setInterval(3000); // 3秒重试
    connect(m_reconnectTimer, &QTimer::timeout, this, &LocalSocketClient::attemptReconnect);
}

功能:初始化 socket 和重连定时器,建立所有信号槽连接

连接管理函数

connectToServer()

复制代码
void LocalSocketClient::connectToServer()
{
    if (m_socket->state() != QLocalSocket::ConnectedState) {
        m_socket->connectToServer("MyLocalServer");  // 连接到指定服务器名
        qDebug() << "Attempting to connect to server...";
        emit statusMessage("Connecting to server...");
    }
}

功能:尝试连接到本地服务器

条件:仅在未连接状态下执行

输出:发送状态消息到 UI

disconnectFromServer()

复制代码
void LocalSocketClient::disconnectFromServer()
{
    if (m_socket->state() == QLocalSocket::ConnectedState) {
        m_socket->disconnectFromServer();  // 主动断开连接
        m_reconnectTimer->stop();           // 停止自动重连
    }
}

功能:主动断开服务器连接并停止重连

消息发送函数

sendMessage(const QString &message)

复制代码
void LocalSocketClient::sendMessage(const QString &message)
{
    if (m_socket->state() == QLocalSocket::ConnectedState) {
        // 构造 JSON 消息
        QJsonObject json;
        json["type"] = "message";
        json["content"] = message;
        json["timestamp"] = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

        QJsonDocument doc(json);
        QByteArray data = doc.toJson(QJsonDocument::Compact) + "\n";  // 添加换行符作为消息分隔

        m_socket->write(data);  // 发送数据
        m_socket->flush();      // 立即刷新缓冲区
        qDebug() << "Client sent:" << message;
        emit messageSent(message);  // 通知 UI 消息已发送
    } else {
        emit statusMessage("Error: Not connected to server");
    }
}

功能:将消息封装为 JSON 格式并通过 socket 发送

特点:添加时间戳,使用换行符分隔消息

自动重连控制

startAutoReconnect() / stopAutoReconnect()

复制代码
void LocalSocketClient::startAutoReconnect()
{
    if (!m_reconnectTimer->isActive()) {
        m_reconnectTimer->start();  // 启动重连定时器
        emit statusMessage("Auto-reconnect enabled");
    }
}

void LocalSocketClient::stopAutoReconnect()
{
    if (m_reconnectTimer->isActive()) {
        m_reconnectTimer->stop();   // 停止重连定时器
        emit statusMessage("Auto-reconnect disabled");
    }
}

attemptReconnect()

复制代码
void LocalSocketClient::attemptReconnect()
{
    if (m_socket->state() == QLocalSocket::UnconnectedState) {
        qDebug() << "Attempting to reconnect...";
        connectToServer();  // 重新连接
    }
}

功能:在断开连接时自动尝试重新连接

状态查询函数

connected()

复制代码
bool LocalSocketClient::connected() const
{
    return m_socket->state() == QLocalSocket::ConnectedState;
}

功能:返回当前是否已连接

connectionStatus()

复制代码
QString LocalSocketClient::connectionStatus() const
{
    switch (m_socket->state()) {
    case QLocalSocket::ConnectedState:
        return "Connected";
    case QLocalSocket::ConnectingState:
        return "Connecting...";
    case QLocalSocket::UnconnectedState:
        return "Disconnected";
    default:
        return "Unknown";
    }
}

功能:返回详细的连接状态字符串

信号处理槽函数

onConnected()

复制代码
void LocalSocketClient::onConnected()
{
    qDebug() << "Connected to server!";
    emit connectedChanged();         // 通知属性变化
    emit connectionStatusChanged();  // 通知状态变化
    emit statusMessage("Connected to server successfully");
    m_reconnectTimer->stop();        // 连接成功,停止重连定时器
}

功能:处理连接成功事件

onDisconnected()

复制代码
void LocalSocketClient::onDisconnected()
{
    qDebug() << "Disconnected from server";
    emit connectedChanged();
    emit connectionStatusChanged();
    emit statusMessage("Disconnected from server");

    // 如果启用自动重连,则启动定时器
    if (m_autoReconnect) {
        m_reconnectTimer->start();
    }
}

功能:处理连接断开事件

onError(QLocalSocket::LocalSocketError error)

复制代码
void LocalSocketClient::onError(QLocalSocket::LocalSocketError error)
{
    qDebug() << "Socket error:" << m_socket->errorString();
    emit statusMessage("Error: " + m_socket->errorString());
}

功能:处理 socket 错误

数据读取函数

readData()

复制代码
void LocalSocketClient::readData()
{
    while (m_socket->canReadLine()) {  // 确保读取完整的一行
        QByteArray data = m_socket->readLine().trimmed();  // 读取并去除空白
        QJsonDocument doc = QJsonDocument::fromJson(data); // 解析 JSON

        if (!doc.isNull()) {
            QJsonObject json = doc.object();
            QString type = json["type"].toString();
            QString content = json["content"].toString();
            QString timestamp = json["timestamp"].toString();

            qDebug() << "Client received - Type:" << type << "Content:" << content;
            emit messageReceived("[" + timestamp + "] " + content);  // 格式化后发送到 UI
        }
    }
}

功能:读取并解析从服务器接收的数据

特点:使用 canReadLine() 确保读取完整消息

LocalSocketServer 类详细分析

构造函数

复制代码
LocalSocketServer::LocalSocketServer(QObject *parent) : QObject(parent)
{
    m_server = new QLocalServer(this);

    // 移除可能存在的旧服务器
    QLocalServer::removeServer("MyLocalServer");

    // 启动服务器监听
    if (!m_server->listen("MyLocalServer")) {
        qDebug() << "Server failed to start:" << m_server->errorString();
        return;
    }

    qDebug() << "Server started successfully, waiting for connections...";

    connect(m_server, &QLocalServer::newConnection, this, &LocalSocketServer::handleNewConnection);
}

关键点:removeServer() 清理可能存在的旧实例

消息发送函数

sendMessageToClient(const QString &message)

复制代码
void LocalSocketServer::sendMessageToClient(const QString &message)
{
    if (m_clientSocket && m_clientSocket->state() == QLocalSocket::ConnectedState) {
        // 构造 JSON 消息(格式与客户端相同)
        QJsonObject json;
        json["type"] = "message";
        json["content"] = message;
        json["timestamp"] = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

        QJsonDocument doc(json);
        QByteArray data = doc.toJson(QJsonDocument::Compact) + "\n";

        m_clientSocket->write(data);
        m_clientSocket->flush();
        qDebug() << "Server sent:" << message;
        emit messageSent("Sent: " + message);
    } else {
        emit messageSent("Error: No client connected");
    }
}

连接管理函数

handleNewConnection()

复制代码
void LocalSocketServer::handleNewConnection()
{
    m_clientSocket = m_server->nextPendingConnection();  // 接受新连接
    qDebug() << "New client connected!";

    // 建立新连接的信号槽
    connect(m_clientSocket, &QLocalSocket::readyRead, this, &LocalSocketServer::readData);
    connect(m_clientSocket, &QLocalSocket::disconnected, this, &LocalSocketServer::onClientDisconnected);

    emit clientConnected();  // 通知 UI

    // 发送欢迎消息
    sendMessageToClient("Welcome to server!");
}

功能:处理新客户端连接,发送欢迎消息

onClientDisconnected()

复制代码
void LocalSocketServer::onClientDisconnected()
{
    qDebug() << "Client disconnected";
    if (m_clientSocket) {
        m_clientSocket->deleteLater();  // 安全删除 socket
        m_clientSocket = nullptr;       // 重置指针
    }
    emit clientDisconnected();  // 通知 UI
}

关键点:使用 deleteLater() 安全释放资源

数据读取函数

readData()

复制代码
void LocalSocketServer::readData()
{
    if (!m_clientSocket) return;

    while (m_clientSocket->canReadLine()) {
        QByteArray data = m_clientSocket->readLine().trimmed();
        QJsonDocument doc = QJsonDocument::fromJson(data);

        if (!doc.isNull()) {
            QJsonObject json = doc.object();
            QString type = json["type"].toString();
            QString content = json["content"].toString();
            QString timestamp = json["timestamp"].toString();

            qDebug() << "Server received - Type:" << type << "Content:" << content;
            emit messageSent("Received [" + timestamp + "]: " + content);

            // 自动回复机制
            if (type == "message") {
                sendMessageToClient("Echo: " + content);  // 回显消息
            }
        }
    }
}

特点:实现自动回显功能,收到消息后自动回复

状态查询函数

getServerStatus()

复制代码
QString LocalSocketServer::getServerStatus() const
{
    if (m_server->isListening()) {
        return m_clientSocket ? "Listening - Client Connected" : "Listening - Waiting for client";
    }
    return "Not Listening";
}

功能:返回服务器当前状态

二、所有源码

LocalSocketServer项目文件

LocalSocketServer.h文件源码

复制代码
#ifndef LOCALSOCKETSERVER_H
#define LOCALSOCKETSERVER_H

#include <QObject>
#include <QLocalServer>
#include <QLocalSocket>

class LocalSocketServer : public QObject
{
    Q_OBJECT

public:
    explicit LocalSocketServer(QObject *parent = nullptr);

    Q_INVOKABLE void sendMessageToClient(const QString &message);
    Q_INVOKABLE QString getServerStatus() const;

signals:
    void messageSent(const QString &message);
    void clientConnected();
    void clientDisconnected();

private slots:
    void handleNewConnection();
    void readData();
    void onClientDisconnected();  // 重命名避免冲突

private:
    QLocalServer *m_server;
    QLocalSocket *m_clientSocket = nullptr;
};

#endif // LOCALSOCKETSERVER_H

LocalSocketServer.cpp文件源码

复制代码
#include "localsocketserver.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QDateTime>
#include <QDebug>

LocalSocketServer::LocalSocketServer(QObject *parent) : QObject(parent)
{
    m_server = new QLocalServer(this);

    // 移除可能存在的旧服务器
    QLocalServer::removeServer("MyLocalServer");

    // 启动服务器监听
    if (!m_server->listen("MyLocalServer")) {
        qDebug() << "Server failed to start:" << m_server->errorString();
        return;
    }

    qDebug() << "Server started successfully, waiting for connections...";

    connect(m_server, &QLocalServer::newConnection, this, &LocalSocketServer::handleNewConnection);
}

void LocalSocketServer::sendMessageToClient(const QString &message)
{
    if (m_clientSocket && m_clientSocket->state() == QLocalSocket::ConnectedState) {
        QJsonObject json;
        json["type"] = "message";
        json["content"] = message;
        json["timestamp"] = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

        QJsonDocument doc(json);
        QByteArray data = doc.toJson(QJsonDocument::Compact) + "\n";

        m_clientSocket->write(data);
        m_clientSocket->flush();
        qDebug() << "Server sent:" << message;
        emit messageSent("Sent: " + message);
    } else {
        emit messageSent("Error: No client connected");
    }
}

QString LocalSocketServer::getServerStatus() const
{
    if (m_server->isListening()) {
        return m_clientSocket ? "Listening - Client Connected" : "Listening - Waiting for client";
    }
    return "Not Listening";
}

void LocalSocketServer::handleNewConnection()
{
    m_clientSocket = m_server->nextPendingConnection();
    qDebug() << "New client connected!";

    connect(m_clientSocket, &QLocalSocket::readyRead, this, &LocalSocketServer::readData);
    connect(m_clientSocket, &QLocalSocket::disconnected, this, &LocalSocketServer::onClientDisconnected);

    emit clientConnected();

    // 发送欢迎消息
    sendMessageToClient("Welcome to server!");
}

void LocalSocketServer::readData()
{
    if (!m_clientSocket) return;

    while (m_clientSocket->canReadLine()) {
        QByteArray data = m_clientSocket->readLine().trimmed();
        QJsonDocument doc = QJsonDocument::fromJson(data);

        if (!doc.isNull()) {
            QJsonObject json = doc.object();
            QString type = json["type"].toString();
            QString content = json["content"].toString();
            QString timestamp = json["timestamp"].toString();

            qDebug() << "Server received - Type:" << type << "Content:" << content;
            emit messageSent("Received [" + timestamp + "]: " + content);

            // 发送回复
            if (type == "message") {
                sendMessageToClient("Echo: " + content);
            }
        }
    }
}

void LocalSocketServer::onClientDisconnected()
{
    qDebug() << "Client disconnected";
    if (m_clientSocket) {
        m_clientSocket->deleteLater();
        m_clientSocket = nullptr;
    }
    emit clientDisconnected();
}

main.qml文件源码

复制代码
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

ApplicationWindow {
    id: window
    width: 500
    height: 600
    title: "Local Socket Server"
    visible: true

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 10

        GroupBox {
            title: "服务器 状态"
            Layout.fillWidth: true

            ColumnLayout {
                width: parent.width

                RowLayout {
                    Text {
                        text: "状态:"
                        font.bold: true
                    }

                    Text {
                        id: statusText
                        text: server.getServerStatus()
                        color: statusText.text.includes("Connected") ? "green" :
                               statusText.text.includes("Listening") ? "blue" : "red"
                    }
                }

                Text {
                    text: "服务器"
                    font.pixelSize: 12
                    color: "gray"
                }
            }
        }

        GroupBox {
            title: "发送消息给 Client"
            Layout.fillWidth: true

            ColumnLayout {
                width: parent.width

                TextField {
                    id: messageField
                    Layout.fillWidth: true
                    placeholderText: "消息"
                    onAccepted: sendButton.clicked()
                }

                Button {
                    id: sendButton
                    text: "发送消息"
                    Layout.fillWidth: true
                    onClicked: {
                        if (messageField.text.trim() !== "") {
                            server.sendMessageToClient(messageField.text)
                            messageField.clear()
                        }
                    }
                }
            }
        }

        GroupBox {
            title: "通讯 日志"
            Layout.fillWidth: true
            Layout.fillHeight: true

            ColumnLayout {
                width: parent.width
                height: parent.height

                ScrollView {
                    Layout.fillWidth: true
                    Layout.fillHeight: true

                    TextArea {
                        id: logArea
                        readOnly: true
                        wrapMode: TextArea.Wrap
                        placeholderText: "Communication log will appear here..."
                        textFormat: TextEdit.PlainText
                    }
                }

                Button {
                    text: "清除日志"
                    Layout.fillWidth: true
                    onClicked: logArea.clear()
                }
            }
        }
    }

    Connections {
        target: server
        onMessageSent: {
            logArea.append(message)
        }
        onClientConnected: {
            logArea.append("*** Client Connected ***")
        }
        onClientDisconnected: {
            logArea.append("*** Client Disconnected ***")
        }
    }

    Component.onCompleted: {
        logArea.append("*** 服务器 启动 ***")
        logArea.append("等待客户连接...")
    }
}

main.cpp文件源码

复制代码
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "localsocketserver.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    LocalSocketServer server;

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("server", &server);

    // 使用正确的 QML 文件路径
    const QUrl url(QStringLiteral("qrc:/main.qml"));

    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl) {
            qDebug() << "Failed to load QML file:" << objUrl;
            QCoreApplication::exit(-1);
        } else {
            qDebug() << "QML loaded successfully";
        }
    }, Qt::QueuedConnection);

    engine.load(url);

    if (engine.rootObjects().isEmpty()) {
        qDebug() << "No root objects created, exiting...";
        return -1;
    }

    return app.exec();
}

LocalSocketClient项目文件

LocalSocketClient.h文件源码

复制代码
#ifndef LOCALSOCKETCLIENT_H
#define LOCALSOCKETCLIENT_H

#include <QObject>
#include <QLocalSocket>
#include <QTimer>

class LocalSocketClient : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
    Q_PROPERTY(QString connectionStatus READ connectionStatus NOTIFY connectionStatusChanged)

public:
    explicit LocalSocketClient(QObject *parent = nullptr);

    Q_INVOKABLE void connectToServer();
    Q_INVOKABLE void disconnectFromServer();
    Q_INVOKABLE void sendMessage(const QString &message);
    Q_INVOKABLE void startAutoReconnect();
    Q_INVOKABLE void stopAutoReconnect();

    bool connected() const;
    QString connectionStatus() const;

signals:
    void connectedChanged();
    void connectionStatusChanged();
    void messageReceived(const QString &message);
    void messageSent(const QString &message);
    void statusMessage(const QString &message);

private slots:
    void onConnected();
    void onDisconnected();
    void onError(QLocalSocket::LocalSocketError error);
    void readData();
    void attemptReconnect();

private:
    QLocalSocket *m_socket;
    QTimer *m_reconnectTimer;
    bool m_autoReconnect = true;
};

#endif // LOCALSOCKETCLIENT_H

LocalSocketClient.cpp文件源码

复制代码
#include "localsocketclient.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QDateTime>
#include <QDebug>

LocalSocketClient::LocalSocketClient(QObject *parent) : QObject(parent)
{
    m_socket = new QLocalSocket(this);

    connect(m_socket, &QLocalSocket::connected, this, &LocalSocketClient::onConnected);
    connect(m_socket, &QLocalSocket::disconnected, this, &LocalSocketClient::onDisconnected);
    connect(m_socket, &QLocalSocket::readyRead, this, &LocalSocketClient::readData);
    connect(m_socket, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error),
            this, &LocalSocketClient::onError);

    // 自动重连定时器
    m_reconnectTimer = new QTimer(this);
    m_reconnectTimer->setInterval(3000); // 3秒重试
    connect(m_reconnectTimer, &QTimer::timeout, this, &LocalSocketClient::attemptReconnect);
}

void LocalSocketClient::connectToServer()
{
    if (m_socket->state() != QLocalSocket::ConnectedState) {
        m_socket->connectToServer("MyLocalServer");
        qDebug() << "Attempting to connect to server...";
        emit statusMessage("Connecting to server...");
    }
}

void LocalSocketClient::disconnectFromServer()
{
    if (m_socket->state() == QLocalSocket::ConnectedState) {
        m_socket->disconnectFromServer();
        m_reconnectTimer->stop();
    }
}

void LocalSocketClient::sendMessage(const QString &message)
{
    if (m_socket->state() == QLocalSocket::ConnectedState) {
        QJsonObject json;
        json["type"] = "message";
        json["content"] = message;
        json["timestamp"] = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

        QJsonDocument doc(json);
        QByteArray data = doc.toJson(QJsonDocument::Compact) + "\n";

        m_socket->write(data);
        m_socket->flush();
        qDebug() << "Client sent:" << message;
        emit messageSent(message);
    } else {
        emit statusMessage("Error: Not connected to server");
    }
}

void LocalSocketClient::startAutoReconnect()
{
    if (!m_reconnectTimer->isActive()) {
        m_reconnectTimer->start();
        emit statusMessage("Auto-reconnect enabled");
    }
}

void LocalSocketClient::stopAutoReconnect()
{
    if (m_reconnectTimer->isActive()) {
        m_reconnectTimer->stop();
        emit statusMessage("Auto-reconnect disabled");
    }
}

bool LocalSocketClient::connected() const
{
    return m_socket->state() == QLocalSocket::ConnectedState;
}

QString LocalSocketClient::connectionStatus() const
{
    switch (m_socket->state()) {
    case QLocalSocket::ConnectedState:
        return "Connected";
    case QLocalSocket::ConnectingState:
        return "Connecting...";
    case QLocalSocket::UnconnectedState:
        return "Disconnected";
    default:
        return "Unknown";
    }
}

void LocalSocketClient::onConnected()
{
    qDebug() << "Connected to server!";
    emit connectedChanged();
    emit connectionStatusChanged();
    emit statusMessage("Connected to server successfully");
    m_reconnectTimer->stop();
}

void LocalSocketClient::onDisconnected()
{
    qDebug() << "Disconnected from server";
    emit connectedChanged();
    emit connectionStatusChanged();
    emit statusMessage("Disconnected from server");

    // 自动重连
    if (m_autoReconnect) {
        m_reconnectTimer->start();
    }
}

void LocalSocketClient::onError(QLocalSocket::LocalSocketError error)
{
    qDebug() << "Socket error:" << m_socket->errorString();
    emit statusMessage("Error: " + m_socket->errorString());
}

void LocalSocketClient::readData()
{
    while (m_socket->canReadLine()) {
        QByteArray data = m_socket->readLine().trimmed();
        QJsonDocument doc = QJsonDocument::fromJson(data);

        if (!doc.isNull()) {
            QJsonObject json = doc.object();
            QString type = json["type"].toString();
            QString content = json["content"].toString();
            QString timestamp = json["timestamp"].toString();

            qDebug() << "Client received - Type:" << type << "Content:" << content;
            emit messageReceived("[" + timestamp + "] " + content);
        }
    }
}

void LocalSocketClient::attemptReconnect()
{
    if (m_socket->state() == QLocalSocket::UnconnectedState) {
        qDebug() << "Attempting to reconnect...";
        connectToServer();
    }
}

main.qml文件源码

复制代码
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

ApplicationWindow {
    id: window
    width: 500
    height: 600
    title: "Local Socket Client"
    visible: true

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 10

        GroupBox {
            title: "Connection Status"
            Layout.fillWidth: true

            ColumnLayout {
                width: parent.width

                RowLayout {
                    Text {
                        text: "Status:"
                        font.bold: true
                    }

                    Text {
                        id: statusText
                        text: client.connectionStatus
                        color: client.connected ? "green" :
                               statusText.text === "Connecting..." ? "orange" : "red"
                    }
                }

                Text {
                    text: "Server: MyLocalServer"
                    font.pixelSize: 12
                    color: "gray"
                }

                RowLayout {
                    Button {
                        text: "Connect"
                        enabled: !client.connected
                        onClicked: client.connectToServer()
                    }

                    Button {
                        text: "Disconnect"
                        enabled: client.connected
                        onClicked: client.disconnectFromServer()
                    }
                }

                RowLayout {
                    CheckBox {
                        id: autoReconnectCheck
                        text: "Auto Reconnect"
                        checked: true
                        onCheckedChanged: {
                            if (checked) {
                                client.startAutoReconnect()
                            } else {
                                client.stopAutoReconnect()
                            }
                        }
                    }
                }
            }
        }

        GroupBox {
            title: "Send Message"
            Layout.fillWidth: true
            enabled: client.connected

            ColumnLayout {
                width: parent.width

                TextField {
                    id: messageField
                    Layout.fillWidth: true
                    placeholderText: "Enter message to send"
                    onAccepted: sendButton.clicked()
                }

                Button {
                    id: sendButton
                    text: "Send Message"
                    Layout.fillWidth: true
                    onClicked: {
                        if (messageField.text.trim() !== "") {
                            client.sendMessage(messageField.text)
                            messageField.clear()
                        }
                    }
                }
            }
        }

        GroupBox {
            title: "Communication Log"
            Layout.fillWidth: true
            Layout.fillHeight: true

            ColumnLayout {
                width: parent.width
                height: parent.height

                ScrollView {
                    Layout.fillWidth: true
                    Layout.fillHeight: true

                    TextArea {
                        id: logArea
                        readOnly: true
                        wrapMode: TextArea.Wrap
                        placeholderText: "Communication log will appear here..."
                        textFormat: TextEdit.PlainText
                    }
                }

                RowLayout {
                    Button {
                        text: "Clear Log"
                        Layout.fillWidth: true
                        onClicked: logArea.clear()
                    }

                    Button {
                        text: "Test Message"
                        Layout.fillWidth: true
                        onClicked: {
                            if (client.connected) {
                                client.sendMessage("Hello from client at " +
                                    new Date().toLocaleTimeString(Qt.locale(), "hh:mm:ss"))
                            }
                        }
                    }
                }
            }
        }
    }

    Connections {
        target: client
        onMessageReceived: {
            logArea.append("RECEIVED: " + message)
        }
        onMessageSent: {
            logArea.append("SENT: " + message)
        }
        onStatusMessage: {
            logArea.append("*** " + message + " ***")
        }
        onConnectedChanged: {
            if (client.connected) {
                logArea.append("*** CONNECTED TO SERVER ***")
            } else {
                logArea.append("*** DISCONNECTED FROM SERVER ***")
            }
        }
    }

    Component.onCompleted: {
        logArea.append("*** Client Started ***")
        logArea.append("Click 'Connect' to connect to the server")

        // 自动连接
        Qt.callLater(client.connectToServer)
    }
}

main.cpp文件源码

复制代码
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "localsocketclient.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QCoreApplication::setApplicationName("Local Socket Client");
    QCoreApplication::setApplicationVersion("1.0");

    LocalSocketClient client;

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("client", &client);

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

三、效果演示

打开服务器和客户端连接后,可以测试发送和接收消息。

相关推荐
微露清风5 小时前
系统性学习C++-第五讲-内存管理
java·c++·学习
星夜钢琴手6 小时前
推荐的 Visual Studio 2026 Insider C++ 程序项目属性配置
c++·visual studio
kyle~7 小时前
Qt---setAttribute设置控件或窗口的内部属性
服务器·前端·c++·qt
hsjkdhs7 小时前
C++之多态
开发语言·jvm·c++
四维碎片7 小时前
【Qt】乌班图安装Qt环境
开发语言·数据库·qt
kyle~7 小时前
C++STL---静态数组array
开发语言·c++
蓝天智能8 小时前
QT MVC中Model的特点及使用注意事项
qt·mvc
kk”8 小时前
C++ List
开发语言·c++
玄魂8 小时前
VTable Gantt 智能 zoom(缩放)功能介绍与开发实践
前端·开源·数据可视化