使用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, dnsServers0);

if (dnsServers.size() > 1) {

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

}

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.145454

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

相关推荐
CRMEB系统商城1 小时前
家电零售的供应商协同与物流提效
java·开发语言·人工智能·小程序·1024程序员节
王大师王文峰1 小时前
Java+AI 面试题(二):业务场景设计 10 例【客服机器人、合同审查、Text2SQL、告警降噪、成本优化】场景题答法与追问链路
java·开发语言·人工智能
言乐61 小时前
Python实现三轴联动根据数据自动打磨镜片模型
开发语言·python
CHHH_HHH2 小时前
【Linux网络篇】初识网络与Socket编程基础
linux·服务器·c语言·开发语言·网络·后端·1024程序员节
jimy12 小时前
C++ 中 xvalue 的 identity 存在哪里?和 lvalue 的 identity 有什么区别?
开发语言·c++·1024程序员节
yujunl2 小时前
U9 无授权的模式WebAPI开发的总结
开发语言·1024程序员节
zzu123zsw2 小时前
为什么 Python 做 Agent 总在并发中崩溃?拆解 Blockcell 在 Rust 下的 Host-Cell 隔离与自愈状态机
开发语言·python·rust·大模型·ai agent
xiaoye-duck2 小时前
《C++ 项目:手写大模型接入 SDK》Provider分析与实现
开发语言·c++·语言模型
denlaku3 小时前
JDK 22 新特性详解
java·开发语言
kaixin_learn_qt_ing3 小时前
Qt开发工程师
qt