跨进程通信之QLocalSocket
跨进程通信之QLocalSocket
苏轼 - 《临江仙·送钱穆父》
一别都门三改火,天涯踏尽红尘。
依然一笑作春温。
无波真古井,有节是秋筠。惆怅孤帆连夜发,送行淡月微云。
尊前不用翠眉颦。
人生如逆旅,我亦是行人。

QLocalSocket 和 QLocalServer。这是在 同一台机器上进行进程间通信(IPC) 的Qt解决方案。
graph TD
A[本地进程间通信 IPC] --> B[QLocalServer]
A --> C[QLocalSocket]
B --> D[服务器端<br>监听连接]
C --> E[客户端<br>发起连接]
D --> F[基于系统本地套接字<br>Windows: 命名管道<br>Unix: Unix Domain Socket]
E --> F
F --> G[高性能<br>无需网络协议栈<br>数据不经过网卡]
是什么?
QLocalServer:类似于QTcpServer,但用于本地连接。它监听一个"服务器名称",等待客户端连接。QLocalSocket:类似于QTcpSocket,但用于本地连接。客户端用它连接到QLocalServer。
工作原理
它们基于操作系统的本地进程通信机制:
- Windows:命名管道(Named Pipes)
- Unix/Linux/macOS:Unix 域套接字(Unix Domain Sockets)
优势:比网络通信更快、更安全(不经过网络接口卡)。
使用案例(Qt官方案例 localfortuneclient/localfortuneserver)
QLocalSocket端核心代码
本地服务器端发送的报文格式:
QDataStream out(&block, QIODevice::WriteOnly);
out << quint32(message.size());
out << message;
Client::Client()
{
QLocalSocket* localSocket = new QLocalSocket(this);
// 连接本地服务器
connect(pshBtnConnectServer, &QPushButton::clicked, [&]()
{
localSocket->abort();
localSocket->connectToServer(hostLineEdit->text());
// 后续逻辑,每个指定间隔,重新连接服务器.
});
// 从服务器读取类容(简化版接收代码)
connect(pshBtnReadFromServer, &QPushButton::readyRead, [&]()
{
QDataStream in;
in >> blockSize >> nextFortune;
});
// 显示网络问题
connect(pshBtnNetError, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error), [&](QLocalSocket::LocalSocketError socketError)
{
switch (socketError) {
case QLocalSocket::ServerNotFoundError:
break;
case QLocalSocket::ConnectionRefusedError:
break;
case QLocalSocket::PeerClosedError:
break;
default:
}
});
}
QLocalServer端核心代码
Client::Client()
{
QLocalServer* server = new QLocalServer(this);
if (!server->listen("fortune"))
{
return;
}
// 获取到来自客户端的一个新连接, 此段代码逻辑为: 客户端每个1s重新连接服务器,服务器每次接收到新连接后,向Peer对象发送数据,同时断开连接。迎接客户端的下一次连接。
connect(server, &QLocalServer::newConnection, [&]()
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_10);
const int fortuneIndex = QRandomGenerator::global()->bounded(0, fortunes.size());
const QString &message = fortunes.at(fortuneIndex);
out << quint32(message.size());
out << message;
QLocalSocket *clientConnection = server->nextPendingConnection();
connect(clientConnection, &QLocalSocket::disconnected,
clientConnection, &QLocalSocket::deleteLater);
clientConnection->write(block);
clientConnection->flush();
clientConnection->disconnectFromServer();
});
}
应用场景
- 主程序与插件通信: 主程序作为服务器,插件作为客户端;
- 多进程协作 : 多个进程通过本地socket协调工作;
- 守护进程与服务 : 系统服务与GUI应用程序通信;
- 进程间数据共享 : 传输配置、状态信息等;
浙公网安备 33010602011771号