用qt写一段代码实现两个上位机通过代理连接两个下位机,两个上位机同一时刻只能有一个可以对下位机发命令,两个下位机收到命令后会发送的数据,发送的数据会在两台上位机上同时显示出来
时间: 2024-03-23 18:37:23 浏览: 48
高分项目,QT上位机,QT四轴上位机初级版,内含完整源代码+下位机协议
好的,下面是一个基于 Qt 的示例代码,实现两个上位机通过代理连接两个下位机,两个上位机同一时刻只能有一个可以对下位机发命令,两个下位机收到命令后会发送的数据,发送的数据会在两台上位机上同时显示出来。需要注意的是,这只是一个示例代码,具体实现还需要根据你的具体需求来修改。
```cpp
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpSocket>
#include <QTcpServer>
#include <QHostAddress>
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_connectBtn_clicked();
void on_sendBtn_clicked();
void on_socketReadyRead();
void on_socketError(QAbstractSocket::SocketError error);
void on_serverNewConnection();
void on_serverReadyRead();
void on_serverError(QAbstractSocket::SocketError error);
private:
Ui::MainWindow *ui;
QTcpSocket *socket;
QTcpServer *server;
QTcpSocket *client;
QTimer *timer;
bool isMaster;
};
#endif // MAINWINDOW_H
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
socket(nullptr),
server(nullptr),
client(nullptr),
timer(nullptr),
isMaster(false)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_connectBtn_clicked()
{
if (socket == nullptr && server == nullptr && client == nullptr) {
// 创建 socket 客户端
socket = new QTcpSocket(this);
connect(socket, &QTcpSocket::readyRead, this, &MainWindow::on_socketReadyRead);
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(on_socketError(QAbstractSocket::SocketError)));
// 创建 socket 服务器
server = new QTcpServer(this);
connect(server, &QTcpServer::newConnection, this, &MainWindow::on_serverNewConnection);
connect(server, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(on_serverError(QAbstractSocket::SocketError)));
// 启动服务器监听
if (!server->listen(QHostAddress::Any, 1234)) {
qDebug() << "Error: " << server->errorString();
return;
}
// 创建定时器
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, [this](){
if (isMaster) {
ui->statusLabel->setText("Master");
ui->sendBtn->setEnabled(true);
ui->dataEdit->setEnabled(true);
if (socket->state() == QAbstractSocket::ConnectedState) {
socket->write("query"); // 发送查询命令
}
} else {
ui->statusLabel->setText("Slave");
ui->sendBtn->setEnabled(false);
ui->dataEdit->setEnabled(false);
}
});
timer->start(2000); // 每 2 秒钟查询一次
qDebug() << "Server started.";
}
}
void MainWindow::on_sendBtn_clicked()
{
if (socket != nullptr && socket->state() == QAbstractSocket::ConnectedState) {
QString data = ui->dataEdit->text();
if (!data.isEmpty()) {
socket->write(data.toUtf8());
ui->dataEdit->clear();
}
}
}
void MainWindow::on_socketReadyRead()
{
QByteArray data = socket->readAll();
ui->recvEdit->append(QString(data));
}
void MainWindow::on_socketError(QAbstractSocket::SocketError error)
{
qDebug() << "Socket error: " << error;
socket->close();
delete socket;
socket = nullptr;
}
void MainWindow::on_serverNewConnection()
{
if (client == nullptr) {
client = server->nextPendingConnection();
connect(client, &QTcpSocket::readyRead, this, &MainWindow::on_serverReadyRead);
connect(client, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(on_serverError(QAbstractSocket::SocketError)));
qDebug() << "Client connected.";
} else {
QTcpSocket *newClient = server->nextPendingConnection();
newClient->close();
delete newClient;
qDebug() << "Another client tried to connect, but rejected.";
}
}
void MainWindow::on_serverReadyRead()
{
QByteArray data = client->readAll();
ui->recvEdit->append(QString(data));
if (isMaster) {
// 主机收到数据后,将数据转发给从机
if (socket != nullptr && socket->state() == QAbstractSocket::ConnectedState) {
socket->write(data);
}
}
}
void MainWindow::on_serverError(QAbstractSocket::SocketError error)
{
qDebug() << "Server error: " << error;
if (client != nullptr) {
client->close();
delete client;
client = nullptr;
}
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if (socket != nullptr) {
socket->close();
delete socket;
socket = nullptr;
}
if (server != nullptr) {
server->close();
delete server;
server = nullptr;
}
if (client != nullptr) {
client->close();
delete client;
client = nullptr;
}
if (timer != nullptr) {
timer->stop();
delete timer;
timer = nullptr;
}
QMainWindow::closeEvent(event);
}
```
这里的实现思路是,通过一个定时器来控制两个上位机之间的命令发送权限。定时器每隔一定时间向下位机发送一个查询命令,下位机收到查询命令后会立即返回数据。如果此时两个上位机都处于连接状态,那么主机就会获得发送数据的权限,否则从机就会获得发送数据的权限。主机收到数据后,会将数据转发给从机。两个上位机接收数据的方式是相同的,都是通过一个 socket 服务器来实现的。
阅读全文