Qt--共享内存监听工具

共享内存概述

共享内存的特点:

1)共享内存是进程共享数据的一种最快的方法。

一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。

2)使用共享内存要注意的是多个进程之间对一个给定存储区域访问的互斥。

若一个进程正在向共享内存区写数据,则在它做完这一步操作前,别的进程不应当去读写这些数据。

共享内存示意图:

共享内存是进程间通信方式中效率最高的,原因在于进程是直接在物理内存上进行操作地址映射到用户进程,所以只要对其地址进行操作,就是直接对物理地址操作。

 

使用共享内存实现进程间的通信的监听手段不比网络通信的监听手段多,由于开发调试需要,使用QT开发了一个小工具,启动一个新的进程软件,连接入需要监听的共享内存块,周期性读取内存中的数据并将其以固定格式写入文本文件,效果如下:

      

 

 源码解析:

mainwindow.h

 1 #ifndef MAINWINDOW_H
 2 #define MAINWINDOW_H
 3 
 4 #include <QMainWindow>
 5 #include <QFile>
 6 #include <QTextStream>
 7 #include <QTextCodec>
 8 #include <QDataStream>
 9 #include <QDateTime>
10 #include <QTimer>
11 #include <QSharedMemory>
12 #include <QDebug>
13 #include <QMessageBox>
14 
15 namespace Ui {
16 class MainWindow;
17 }
18 
19 class MainWindow : public QMainWindow
20 {
21     Q_OBJECT
22 
23 public:
24     explicit MainWindow(QWidget *parent = 0);
25     ~MainWindow();
26 
27 private slots:
28     void on_pushButtonStart_clicked();
29 
30     void on_pushButton_clicked();
31 
32 private:
33     Ui::MainWindow *ui;
34 
35     QTimer *mTimer;
36 
37     QSharedMemory sharedMemoryWrite;
38     quint16 dataLen;
39 
40     void writeToFile(const QByteArray &byteArray, const QString &fileName);
41     void writeToBin(const QByteArray &byteArray, const QString &fileName);
42     void writeToHex(const QByteArray &byteArray, const QString &fileName);
43     QString getCurrentDateTime();
44 
45 public slots:
46     void readMemoryData();
47 };
48 
49 #endif // MAINWINDOW_H
View Code

 

mainwindow.cpp

  1 #include "mainwindow.h"
  2 #include "ui_mainwindow.h"
  3 
  4 MainWindow::MainWindow(QWidget *parent) :
  5     QMainWindow(parent),
  6     ui(new Ui::MainWindow)
  7 {
  8     ui->setupUi(this);
  9     ui->pushButtonStart->setStyleSheet("background-color: green");
 10     ui->pushButton->setStyleSheet("background-color: red");
 11 
 12     //定时器初始化
 13     mTimer = new QTimer();
 14     connect(mTimer,&QTimer::timeout,this,&MainWindow::readMemoryData);
 15 
 16 }
 17 
 18 MainWindow::~MainWindow()
 19 {
 20     delete ui;
 21 }
 22 
 23 //定时器激活按钮点击事件
 24 void MainWindow::on_pushButtonStart_clicked()
 25 {
 26     static bool state = false;
 27     state = !state;
 28     if(state)
 29     {
 30         ui->pushButtonStart->setStyleSheet("background-color: red");
 31         ui->pushButtonStart->setText("Stop");
 32 
 33         //开启读取定时
 34         if(mTimer->isActive() == false)
 35         {
 36             mTimer->start(250);
 37         }
 38     }
 39     else
 40     {
 41         ui->pushButtonStart->setStyleSheet("background-color: green");
 42         ui->pushButtonStart->setText("Start");
 43 
 44         //停止读取定时器
 45         if(mTimer->isActive() == true)
 46         {
 47             mTimer->stop();
 48         }
 49     }
 50 }
 51 
 52 //包含写入时间,写入ASCII格式
 53 void MainWindow::writeToFile(const QByteArray &byteArray, const QString &fileName)
 54 {
 55     QFile file(fileName);
 56     //文件打开方式写入和追加
 57     if (!file.open(QIODevice::WriteOnly | QIODevice::Append))
 58     {
 59         // 处理错误,例如可以抛出异常或者返回错误标志
 60         return;
 61     }
 62     //初始化流
 63     QTextStream out(&file);
 64     //设置中文格式,避免乱码
 65     QTextCodec *tc = QTextCodec::codecForName("GBK");
 66     //QByteArray转换为QString
 67     QString str = tc->toUnicode(byteArray);
 68     //写入时间
 69     out << getCurrentDateTime() << " " <<str;
 70     //换行用于区分不同周期数据
 71     out << "\n";
 72     //文件关闭
 73     file.close();
 74 }
 75 
 76 //十六进制转字符串写入文件
 77 void MainWindow::writeToHex(const QByteArray &byteArray, const QString &fileName)
 78 {
 79     QFile file(fileName);
 80     //文件打开方式写入和追加
 81     if (!file.open(QIODevice::WriteOnly | QIODevice::Append))
 82     {
 83         // 处理错误,例如可以抛出异常或者返回错误标志
 84         return;
 85     }
 86     //初始化流
 87     QTextStream out(&file);
 88     //设置中文格式,避免乱码
 89     QTextCodec *tc = QTextCodec::codecForName("GBK");
 90     //QByteArray格式转换为十六进制
 91     QString str = tc->toUnicode(byteArray.toHex());
 92     //QRegularExpression(“(…)”)表示匹配两个字符,replace()函数将匹配到的字符用"\1 “替换
 93     out << str.replace(QRegularExpression("(..)"), "\\1 ");
 94     //换行用于区分不同周期数据
 95     out << "\n";
 96     //文件关闭
 97     file.close();
 98 }
 99 
100 //获取当前时间
101 QString MainWindow::getCurrentDateTime()
102 {
103     // 获取当前日期和时间
104     QDateTime currentDateTime = QDateTime::currentDateTime();
105     // 将日期和时间格式化为字符串
106     // 例如: "2023-03-28 15:04:05"
107     QString dateTimeString = currentDateTime.toString("yyyy-MM-dd hh:mm:ss:zzz");
108 
109     return dateTimeString;
110 }
111 
112 //读取内存定时器
113 void MainWindow::readMemoryData()
114 {
115     QByteArray dataRead;
116     //初始化dataRead缓存的大小
117     dataRead.resize(dataLen);
118 
119     //锁闭内存
120     sharedMemoryWrite.lock();
121     //拷贝内存中的数据到dataRead缓存中
122     memcpy(dataRead.data(),(char*)sharedMemoryWrite.data(),dataRead.length());
123     //释放内存
124     sharedMemoryWrite.unlock();
125 
126     //记录内存中数据到文件
127     QByteArray byteArray = ":";
128     //设置记录文件名称
129     QString fileName = "output.txt";
130     //将当前时间数据写入到文件中
131     writeToFile(byteArray, fileName);
132     //将拷贝出来的内存数据写入到文件中
133     writeToHex(dataRead, fileName);
134 }
135 
136 //连接共享内存事件
137 void MainWindow::on_pushButton_clicked()
138 {
139     static bool state = false;
140 
141     if(state)
142     {
143         //共享内存分离
144         sharedMemoryWrite.detach();
145         ui->pushButton->setStyleSheet("background-color: red");
146         ui->pushButton->setText("DisConnect");
147         state = !state;
148     }
149     else
150     {
151         sharedMemoryWrite.setKey(ui->lineEdit->text());
152         sharedMemoryWrite.detach();//分离
153         bool flag = sharedMemoryWrite.attach();//连接
154         if(!flag)
155         {
156             //内存不存在
157             qDebug()<<ui->lineEdit->text()<<" is not alive";
158             //设置中文格式,避免乱码
159             QTextCodec *tc = QTextCodec::codecForName("GBK");
160             //转换成中文GBK格式
161             QString str = tc->toUnicode("内存不存在,\n请确认内存名称");
162             //弹窗告警
163             QMessageBox::warning(this,"Warning",str);
164             return;
165         }
166         dataLen = sharedMemoryWrite.size();
167         qDebug()<<"Connect "<<ui->lineEdit->text();
168 
169         ui->pushButton->setStyleSheet("background-color: green");
170         ui->pushButton->setText("Connect");
171         state = !state;
172     }
173 
174 }

 

源码下载:

链接: https://pan.baidu.com/s/19-0WgDwdJpGB0A3L87-cBw 提取码: q9cc 复制这段内容后打开百度网盘手机App,操作更方便哦

 

posted @ 2024-04-11 16:55  熊来闯一闯  阅读(228)  评论(0编辑  收藏  举报