可以用CS架构编写这两个仿真器,将设备写成服务器,接收来自工厂控制程序的命令。后续加上半导体设备通信协议。
- 半导体设备服务器
1)工程文件
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
deviceserver.cpp \
main.cpp \
deviceservergui.cpp
HEADERS += \
deviceserver.h \
deviceservergui.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
2)DeviceServer类:
#ifndef DEVICESERVER_H
#define DEVICESERVER_H
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
class DeviceServer : public QObject
{
Q_OBJECT
public:
explicit DeviceServer(QObject *parent = nullptr);
void startServer(quint16 port);
signals:
void dataReceived(const QString &data);
void statusChanged(const QString &status);
private slots:
void newConnection();
void readClientData();
void clientDisconnected();
private:
QTcpServer *tcpServer;
QTcpSocket *clientSocket;
};
#endif // DEVICESERVER_H
#include "DeviceServer.h"
#include <QDebug>
DeviceServer::DeviceServer(QObject *parent) : QObject(parent), tcpServer(new QTcpServer(this)), clientSocket(nullptr)
{
connect(tcpServer, &QTcpServer::newConnection, this, &DeviceServer::newConnection);
}
void DeviceServer::startServer(quint16 port)
{
if (!tcpServer->listen(QHostAddress::Any, port)) {
emit statusChanged("Failed to start server: " + tcpServer->errorString());
return;
}
emit statusChanged("Server started on port " + QString::number(port));
}
void DeviceServer::newConnection()
{
if (clientSocket) {
clientSocket->deleteLater();
}
clientSocket = tcpServer->nextPendingConnection();
connect(clientSocket, &QTcpSocket::readyRead, this, &DeviceServer::readClientData);
connect(clientSocket, &QTcpSocket::disconnected, this, &DeviceServer::clientDisconnected);
emit statusChanged("New client connected");
}
void DeviceServer::readClientData()
{
QByteArray data = clientSocket->readAll();
emit dataReceived(data);
clientSocket->write("Acknowledged");
}
void DeviceServer::clientDisconnected()
{
emit statusChanged("Client disconnected");
clientSocket->deleteLater();
clientSocket = nullptr;
}
3)DeviceServerGUI类
#ifndef DEVICESERVERGUI_H
#define DEVICESERVERGUI_H
#include <QWidget>
#include <QTextEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include "DeviceServer.h"
class DeviceServerGUI : public QWidget
{
Q_OBJECT
public:
explicit DeviceServerGUI(QWidget *parent = nullptr);
private slots:
void startServer();
void handleDataReceived(const QString &data);
void handleStatusChanged(const QString &status);
private:
DeviceServer *deviceServer;
QTextEdit *logTextEdit;
QPushButton *startButton;
};
#endif // DEVICESERVERGUI_H
#include "DeviceServerGUI.h"
#include <QDebug>
DeviceServerGUI::DeviceServerGUI(QWidget *parent)
: QWidget(parent), deviceServer(new DeviceServer(this))
{
QVBoxLayout *layout = new QVBoxLayout(this);
logTextEdit = new QTextEdit(this);
logTextEdit->setReadOnly(true);
layout->addWidget(logTextEdit);
startButton = new QPushButton("Start Server", this);
layout->addWidget(startButton);
setLayout(layout);
connect(startButton, &QPushButton::clicked, this, &DeviceServerGUI::startServer);
connect(deviceServer, &DeviceServer::dataReceived, this, &DeviceServerGUI::handleDataReceived);
connect(deviceServer, &DeviceServer::statusChanged, this, &DeviceServerGUI::handleStatusChanged);
}
void DeviceServerGUI::startServer()
{
deviceServer->startServer(1234); // Start server on port 1234
}
void DeviceServerGUI::handleDataReceived(const QString &data)
{
logTextEdit->append("Received data: " + data);
}
void DeviceServerGUI::handleStatusChanged(const QString &status)
{
logTextEdit->append(status);
}
4)主程序
#include <QApplication>
#include "DeviceServerGUI.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
DeviceServerGUI serverGui;
serverGui.show();
return a.exec();
}
- 工厂控制客户端
1)工程文件
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
factoryclient.cpp \
main.cpp \
factoryclientgui.cpp
HEADERS += \
factoryclient.h \
factoryclientgui.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
2)FactoryClient类
#ifndef FACTORYCLIENT_H
#define FACTORYCLIENT_H
#include <QObject>
#include <QTcpSocket>
class FactoryClient : public QObject
{
Q_OBJECT
public:
explicit FactoryClient(QObject *parent = nullptr);
void connectToServer(const QString &host, quint16 port);
void sendCommand(const QByteArray &command);
signals:
void responseReceived(const QString &response);
void statusChanged(const QString &status);
private slots:
void readServerResponse();
private:
QTcpSocket *tcpSocket;
};
#endif // FACTORYCLIENT_H
#include "FactoryClient.h"
#include <QDebug>
FactoryClient::FactoryClient(QObject *parent) : QObject(parent), tcpSocket(new QTcpSocket(this))
{
connect(tcpSocket, &QTcpSocket::readyRead, this, &FactoryClient::readServerResponse);
}
void FactoryClient::connectToServer(const QString &host, quint16 port)
{
tcpSocket->connectToHost(host, port);
if (!tcpSocket->waitForConnected(3000)) {
emit statusChanged("Failed to connect to server: " + tcpSocket->errorString());
} else {
emit statusChanged("Connected to server");
}
}
void FactoryClient::sendCommand(const QByteArray &command)
{
if (tcpSocket->state() == QTcpSocket::ConnectedState) {
tcpSocket->write(command);
tcpSocket->flush();
} else {
emit statusChanged("Not connected to server");
}
}
void FactoryClient::readServerResponse()
{
QByteArray response = tcpSocket->readAll();
emit responseReceived(response);
}
3)Factory ClientGUI类
#ifndef FACTORYCLIENTGUI_H
#define FACTORYCLIENTGUI_H
#include <QWidget>
#include <QTextEdit>
#include <QPushButton>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include "FactoryClient.h"
class FactoryClientGUI : public QWidget
{
Q_OBJECT
public:
explicit FactoryClientGUI(QWidget *parent = nullptr);
private slots:
void connectToServer();
void sendCommand();
void handleResponseReceived(const QString &response);
void handleStatusChanged(const QString &status);
private:
FactoryClient *factoryClient;
QLineEdit *hostLineEdit;
QLineEdit *portLineEdit;
QLineEdit *commandLineEdit;
QTextEdit *logTextEdit;
QPushButton *connectButton;
QPushButton *sendButton;
};
#endif // FACTORYCLIENTGUI_H
#include "FactoryClientGUI.h"
#include <QDebug>
FactoryClientGUI::FactoryClientGUI(QWidget *parent)
: QWidget(parent), factoryClient(new FactoryClient(this))
{
QVBoxLayout *mainLayout = new QVBoxLayout(this);
QHBoxLayout *connectLayout = new QHBoxLayout();
hostLineEdit = new QLineEdit(this);
hostLineEdit->setPlaceholderText("Host");
connectLayout->addWidget(hostLineEdit);
portLineEdit = new QLineEdit(this);
portLineEdit->setPlaceholderText("Port");
connectLayout->addWidget(portLineEdit);
connectButton = new QPushButton("Connect", this);
connectLayout->addWidget(connectButton);
mainLayout->addLayout(connectLayout);
QHBoxLayout *commandLayout = new QHBoxLayout();
commandLineEdit = new QLineEdit(this);
commandLineEdit->setPlaceholderText("Command");
commandLayout->addWidget(commandLineEdit);
sendButton = new QPushButton("Send Command", this);
commandLayout->addWidget(sendButton);
mainLayout->addLayout(commandLayout);
logTextEdit = new QTextEdit(this);
logTextEdit->setReadOnly(true);
mainLayout->addWidget(logTextEdit);
setLayout(mainLayout);
connect(connectButton, &QPushButton::clicked, this, &FactoryClientGUI::connectToServer);
connect(sendButton, &QPushButton::clicked, this, &FactoryClientGUI::sendCommand);
connect(factoryClient, &FactoryClient::responseReceived, this, &FactoryClientGUI::handleResponseReceived);
connect(factoryClient, &FactoryClient::statusChanged, this, &FactoryClientGUI::handleStatusChanged);
}
void FactoryClientGUI::connectToServer()
{
QString host = hostLineEdit->text();
quint16 port = portLineEdit->text().toUShort();
factoryClient->connectToServer(host, port);
}
void FactoryClientGUI::sendCommand()
{
QByteArray command = commandLineEdit->text().toUtf8();
factoryClient->sendCommand(command);
}
void FactoryClientGUI::handleResponseReceived(const QString &response)
{
logTextEdit->append("Received response: " + response);
}
void FactoryClientGUI::handleStatusChanged(const QString &status)
{
logTextEdit->append(status);
}
4)主程序
#include <QApplication>
#include "FactoryClientGUI.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FactoryClientGUI clientGui;
clientGui.show();
return a.exec();
}