qt 与 python 基于命名管道的进程间通信示例
概述
“命名管道(Named Pipes)”是一种简单的进程间通信(IPC)机制,Microsoft Windows大都提供了对它的支持(但不包括Windows CE)。命名管道可在同一台计算机的不同进程之间或在跨越一个网络的不同计算机的不同进程之间,支持可靠的、单向或双向的数据通信。推荐用命名管道作为进程通信方案的一项重要的原因是它们充分利用了Windows内建的安全特性(ACL等)。
用命名管道来设计跨计算机应用程序实际非常简单,并不需要事先深入掌握底层网络传送协议(如TCP、UDP、IP、IPX)的知识。这是由于命名管道利用了微软网络提供者(MSNP)重定向器通过同一个网络在各进程间建立通信,这样一来,应用程序便不必关心网络协议的细节。(–摘自百度百科)
Qt中 QLocalSocket
通过命名管道实现, 因此可以使用QLocalSocket
和QLocalServer
实现Qt端的命名管道通信.
示例说明
示例程序已上传至CSDN, 点击localserver.zip进行下载.
使用 Qt Creator
打开服务器端示例工程localserver
并运行.运行效果如下图所示.
Test
按钮为禁用状态, 表明客户端未连接. 状态栏显示管道名称.
在工程目录下打开
cmd
或powershell
, 运行客户端Python脚本:
python .\localclient.py
此时, 服务器端界面中Test
按钮变为启用状态, 点击Test
按钮, 服务器端将发送消息’Hello, Python.'到客户端, 客户端收到服务端发来的消息后,将输出至终端并返回消息"Hello, Qt".
服务器端收到客户端返回的消息后,将显示在文本框中. 运行效果如下:
服务器端程序设计(Qt)
工程配置文件
链接network
模块
QT += core gui network
mainwindow.h
添加槽函数声明:
槽函数 | 说明 |
---|---|
newConnection() | 客户端连接服务器端时,执行此方法; |
disconnected() | 客户端断开连接时,执行此方法; |
readData() | 接收到客户端发送的数据时, 执行此方法 |
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
class QLocalServer;
class QLocalSocket;
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
...
private slots:
void on_pushButton_clicked();
/// 客户端连接服务器端时.
void newConnection();
/// 客户端断开连接时.
void disconnected();
/// 接收到客户端发送的数据时
void readData();
private:
Ui::MainWindow *ui;
QLocalServer *server;
QLocalSocket *clientConnection;
};
#endif // MAINWINDOW_H
mainwindow.cpp
包含必要的头文件:
// mainwindow.cpp
#include <QLocalServer>
#include <QLocalSocket>
构造函数:
- 实例化
QLocalServer
, - 连接
server
的newConnection()
信号
MainWindow::MainWindow(QWidget *parent) ...
{
...
server = new QLocalServer(this);
...
connect(server, &QLocalServer::newConnection, this, &MainWindow::newConnection);
}
newConnection() :
- 获取客户端连接
clientConnection
- 连接
clientConnection
的readyRead()
信号 - 连接
clientConnection
的disconnected()
信号 - 启用按钮
void MainWindow::newConnection()
{
clientConnection = server->nextPendingConnection();
connect(clientConnection, &QLocalSocket::readyRead, this, &MainWindow::readData);
connect(clientConnection, &QLocalSocket::disconnected, this, &MainWindow::disconnected);
ui->pushButton->setEnabled(true);
}
readData() :
- 从
clientConnection
读取数据; - 追加数据到文本框.
void MainWindow::readData()
{
char buf[1024] = {0};
clientConnection->read(buf, 1024);
QString msg(buf);
ui->plainTextEdit->appendPlainText(msg);
}
disconnected():
- 删除连接
- 禁用按钮
void MainWindow::disconnected()
{
clientConnection->deleteLater();
ui->pushButton->setEnabled(false);
}
on_pushButton_clicked():
- 向客户端发送数据
void MainWindow::on_pushButton_clicked()
{
char *data = "hello, Python.";
clientConnection->write(data);
}
客户端程序设计(Python)
import os
try:
fd = os.open('\\\\.\\pipe\\fortune', os.O_RDWR)
except FileNotFoundError:
print('Error: Server not running, or pipe name dismatch.')
raise FileNotFoundError
print('Wait recv...')
for k in range(10):
data = os.read(fd, 1024)
print(data)
d = b'Hello, Qt.'
os.write(fd, d)
os.close(fd)