使用Qt Core模块(无GUI依赖),确保程序作为后台服务/daemon运行,与任何GUI完全无交互。

#ifndef BRIDGESYSNETSVC_H

#define BRIDGESYSNETSVC_H

#include <QObject>

#include <QFileSystemWatcher>

#include <QSettings>

#include <QProcess>

#include <QDebug>

class BridgeSysNetSvc : public QObject {

Q_OBJECT

public:

explicit BridgeSysNetSvc(QObject *parent = nullptr);

~BridgeSysNetSvc();

void startMonitoring();

private slots:

void onConfigChanged(const QString &path);

private:

QFileSystemWatcher *watcher;

QString adapterName;

QString ipAddress;

QString subnetMask;

QString gateway;

QStringList dnsServers;

void loadNetworkSettings();

bool modifyNetworkSettings();

};

#endif // BRIDGESYSNETSVC_H

#include "bridgesysnetsvc.h"

#include <QFileInfo>

BridgeSysNetSvc::BridgeSysNetSvc(QObject *parent) : QObject(parent), watcher(nullptr) {

loadNetworkSettings();

watcher = new QFileSystemWatcher(this);

connect(watcher, &QFileSystemWatcher::fileChanged, this, &BridgeSysNetSvc::onConfigChanged);

}

BridgeSysNetSvc::~BridgeSysNetSvc() {

delete watcher;

}

void BridgeSysNetSvc::startMonitoring() {

QSettings settings("config.ini", QSettings::IniFormat);

QString configPath = settings.value("Network/ConfigFilePath").toString();

if (!configPath.isEmpty()) {

watcher->addPath(configPath);

qDebug() << "Monitoring config file:" << configPath;

}

}

void BridgeSysNetSvc::onConfigChanged(const QString &path) {

qDebug() << "Config changed:" << path;

loadNetworkSettings();

if (modifyNetworkSettings()) {

qDebug() << "Network modified successfully. Triggering restart.";

// 退出程序,依赖系统重启

qApp->exit(42); // 自定义退出码,表示成功修改

} else {

qDebug() << "Network modification failed.";

}

}

void BridgeSysNetSvc::loadNetworkSettings() {

QSettings settings("config.ini", QSettings::IniFormat);

adapterName = settings.value("Network/AdapterName").toString();

ipAddress = settings.value("Network/IPAddress").toString();

subnetMask = settings.value("Network/SubnetMask").toString();

gateway = settings.value("Network/Gateway").toString();

dnsServers << settings.value("Network/DNS1").toString()

<< settings.value("Network/DNS2").toString();

}

bool BridgeSysNetSvc::modifyNetworkSettings() {

#ifdef Q_OS_WIN

// Windows: 使用netsh命令

QProcess process;

QStringList cmds;

cmds << QString("interface ip set address \"%1\" static %2 %3 %4").arg(adapterName, ipAddress, subnetMask, gateway);

cmds << QString("interface ip set dns \"%1\" static %2").arg(adapterName, dnsServers[0]);

if (dnsServers.size() > 1) {

cmds << QString("interface ip add dns \"%1\" %2").arg(adapterName, dnsServers[1]);

}

for (const QString &cmd : cmds) {

process.start("netsh", cmd.split(" "));

process.waitForFinished();

if (process.exitCode() != 0) {

qDebug() << "Error:" << process.readAllStandardError();

return false;

}

}

return true;

#elif defined(Q_OS_LINUX)

// Linux (NanoPi): 使用ip命令

QProcess process;

QStringList cmds;

cmds << QString("addr flush dev %1").arg(adapterName);

cmds << QString("addr add %1/%2 dev %3").arg(ipAddress, subnetMask, adapterName); // 注意:掩码需转换为CIDR,但简化假设/24等

cmds << QString("route add default gw %1 dev %2").arg(gateway, adapterName);

// DNS: 修改 /etc/resolv.conf (简单方式,生产中用systemd-resolved)

QFile resolv("/etc/resolv.conf");

if (resolv.open(QIODevice::WriteOnly | QIODevice::Text)) {

QTextStream out(&resolv);

for (const QString &dns : dnsServers) {

out << "nameserver " << dns << "\n";

}

resolv.close();

} else {

qDebug() << "Failed to write resolv.conf";

return false;

}

for (const QString &cmd : cmds) {

process.start("ip", cmd.split(" "));

process.waitForFinished();

if (process.exitCode() != 0) {

qDebug() << "Error:" << process.readAllStandardError();

return false;

}

}

return true;

#else

return false;

#endif

}

#include <QCoreApplication>

#include "bridgesysnetsvc.h"

#ifdef Q_OS_WIN

#include "qtservice.h" // 包含QtService头

class WinService : public QtService<QCoreApplication> {

public:

WinService(int argc, char **argv) : QtService(argc, argv, "BridgeSysNetSvc") {

setServiceDescription("Bridge System Network Service");

setStartupType(QtServiceBase::AutoStartup);

}

protected:

void start() override {

BridgeSysNetSvc svc;

svc.startMonitoring();

}

void stop() override {}

};

#endif

int main(int argc, char *argv[]) {

#ifdef Q_OS_WIN

WinService service(argc, argv);

return service.exec();

#elif defined(Q_OS_LINUX)

// Linux daemon: 简单fork

pid_t pid = fork();

if (pid < 0) return 1;

if (pid > 0) return 0; // 父进程退出

umask(0);

setsid();

QCoreApplication a(argc, argv);

BridgeSysNetSvc svc;

svc.startMonitoring();

return a.exec();

#else

return 1;

#endif

}

06.09.2025 19:34:25.674 INFO root - 收到更新请求,来自: 192.168.137.1[45454]

06.09.2025 19:34:25.739 INFO root - 设置 eth0 IP=192.168.137.240/24 失败 (进程未正常结束)

06.09.2025 19:34:25.741 INFO root - 已发送响应:{"reply":"设置 eth0 IP=192.168.137.240/24 失败 (进程未正常结束)","result":false,"type":"UPDATE_DEVICE_RESPONSE"}

41 ../sysdeps/unix/sysv/linux/poll.c: No such file or directory

相关推荐
Morwit几秒前
Qt qml创建c++类的单例对象
开发语言·c++·qt
古城小栈3 分钟前
Rust 已经自举,却仍需GNU与MSVC工具链的缘由
开发语言·rust
YxVoyager6 分钟前
Qt C++ :QRegularExpression 正则表达式使用详解
c++·qt·正则表达式
jarreyer7 分钟前
数据项目分析标准化流程
开发语言·python·机器学习
你怎么知道我是队长10 分钟前
C语言---printf函数使用详细说明
c语言·开发语言
qq_4017004112 分钟前
QStackedLayout 实现遮罩层
qt
liulilittle12 分钟前
俄罗斯访问欧洲国际线路优化
开发语言·网络·信息与通信·ip·通信·俄罗斯·莫斯科
陈小桔15 分钟前
logging模块-python
开发语言·python
消失的旧时光-194315 分钟前
函数指针 + 结构体 = C 语言的“对象模型”?——从 C 到 C++ / Java 的本质统一
linux·c语言·开发语言·c++·c
!停16 分钟前
C语言栈和队列的实现
开发语言·数据结构