用qt写一段代码实现两个上位机通过代理连接两个下位机,两个上位机可以对下位机发命令,两个下位机收到命令后会发送的数据,发送的数据会在两台上位机上同时显示出来
时间: 2024-03-23 11:38:07 浏览: 45
高分项目,QT上位机,QT四轴上位机初级版,内含完整源代码+下位机协议
感谢您的提问。以下是一份示例代码实现:
```
#include <QTcpSocket>
#include <QTcpServer>
// 定义代理端口
#define PROXY_PORT 8080
// 定义下位机端口
#define DEVICE1_PORT 9001
#define DEVICE2_PORT 9002
// 定义命令类型
enum CommandType {
CMD_DEVICE1,
CMD_DEVICE2
};
class UpstreamClient : public QObject
{
Q_OBJECT
public:
explicit UpstreamClient(QTcpSocket* socket, QObject *parent = nullptr) : QObject(parent), m_socket(socket) {
connect(m_socket, &QTcpSocket::readyRead, this, &UpstreamClient::onReadyRead);
}
signals:
void dataReceived(CommandType cmd, QByteArray data);
public slots:
void sendData(CommandType cmd, const QByteArray& data) {
// 将命令和数据打包发送给下位机
QByteArray packet;
packet.append(static_cast<char>(cmd));
packet.append(data);
m_socket->write(packet);
}
private slots:
void onReadyRead() {
// 读取从下位机发送来的数据
QByteArray data = m_socket->readAll();
// 解析命令和数据
CommandType cmd = static_cast<CommandType>(data[0]);
data.remove(0, 1);
// 发送数据到另一台上位机
emit dataReceived(cmd, data);
}
private:
QTcpSocket* m_socket;
};
class DownstreamServer : public QObject
{
Q_OBJECT
public:
explicit DownstreamServer(int port, QObject *parent = nullptr) : QObject(parent) {
m_server = new QTcpServer(this);
connect(m_server, &QTcpServer::newConnection, this, &DownstreamServer::onNewConnection);
m_server->listen(QHostAddress::Any, port);
}
signals:
void dataReceived(CommandType cmd, QByteArray data);
public slots:
void sendData(CommandType cmd, const QByteArray& data) {
// 将命令和数据打包发送给对应的上位机
QByteArray packet;
packet.append(static_cast<char>(cmd));
packet.append(data);
m_clients[cmd]->write(packet);
}
private slots:
void onNewConnection() {
// 建立连接后创建 UpstreamClient 对象
QTcpSocket* socket = m_server->nextPendingConnection();
UpstreamClient* client = new UpstreamClient(socket, this);
connect(client, &UpstreamClient::dataReceived, this, &DownstreamServer::onDataReceived);
// 保存客户端对象
if (m_clients.count() == 0) {
m_clients.insert(CMD_DEVICE1, socket);
} else {
m_clients.insert(CMD_DEVICE2, socket);
}
}
void onDataReceived(CommandType cmd, QByteArray data) {
// 发送数据到另一台上位机
emit dataReceived(cmd, data);
}
private:
QTcpServer* m_server;
QMap<CommandType, QTcpSocket*> m_clients;
};
class Proxy : public QObject
{
Q_OBJECT
public:
explicit Proxy(QObject *parent = nullptr) : QObject(parent) {
m_downstream1 = new DownstreamServer(DEVICE1_PORT, this);
m_downstream2 = new DownstreamServer(DEVICE2_PORT, this);
connect(m_downstream1, &DownstreamServer::dataReceived, this, &Proxy::onDataReceived);
connect(m_downstream2, &DownstreamServer::dataReceived, this, &Proxy::onDataReceived);
}
signals:
void dataReceived(CommandType cmd, QByteArray data);
public slots:
void sendData(CommandType cmd, const QByteArray& data) {
// 将命令和数据打包发送给对应的下位机
if (cmd == CMD_DEVICE1) {
m_downstream1->sendData(cmd, data);
} else {
m_downstream2->sendData(cmd, data);
}
}
private slots:
void onDataReceived(CommandType cmd, QByteArray data) {
// 将数据发送到另一台上位机
emit dataReceived(cmd, data);
}
private:
DownstreamServer* m_downstream1;
DownstreamServer* m_downstream2;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 创建代理服务器
Proxy proxy;
// 创建两个上位机
QTcpSocket* upstream1 = new QTcpSocket(&a);
QTcpSocket* upstream2 = new QTcpSocket(&a);
// 连接到代理服务器
upstream1->connectToHost(QHostAddress::LocalHost, PROXY_PORT);
upstream2->connectToHost(QHostAddress::LocalHost, PROXY_PORT);
// 处理上位机发送来的命令和数据
QObject::connect(upstream1, &QTcpSocket::readyRead, &a, [=]() {
QByteArray data = upstream1->readAll();
proxy.sendData(CMD_DEVICE1, data);
});
QObject::connect(upstream2, &QTcpSocket::readyRead, &a, [=]() {
QByteArray data = upstream2->readAll();
proxy.sendData(CMD_DEVICE2, data);
});
// 处理代理服务器发送来的数据
QObject::connect(&proxy, &Proxy::dataReceived, &a, [=](CommandType cmd, QByteArray data) {
if (cmd == CMD_DEVICE1) {
upstream2->write(data);
} else {
upstream1->write(data);
}
});
return a.exec();
}
```
该示例代码实现了两个上位机通过代理服务器连接两个下位机,并且可以互相发送命令和数据,数据也会在两台上位机上同时显示出来。其中,代理服务器和下位机之间使用的是 TCP 协议进行通信,上位机和代理服务器之间也是使用 TCP 协议进行通信。您可以根据您的实际需求进行调整和修改。
阅读全文