使用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

相关推荐
歪歪1004 小时前
Qt Creator 打包应用程序时经常会遇到各种问题
开发语言·c++·qt·架构·编辑器
滴滴滴嘟嘟嘟.4 小时前
Qt自定义列表项与QListWidget学习
开发语言·qt·学习
PEI044 小时前
MVCC(多版本并发控制)
java·开发语言·数据库
熊猫钓鱼>_>4 小时前
2025反爬虫之战札记:从robots.txt到多层防御的攻防进化史
开发语言·c++·爬虫
牛十二5 小时前
mac-intel操作系统go-stock项目(股票分析工具)安装与配置指南
开发语言·前端·javascript
励志不掉头发的内向程序员5 小时前
从零开始的python学习——文件
开发语言·python·学习
恒森宇电子有限公司5 小时前
IP5326_BZ 支持C同口输入输出的移动电源芯片 2.4A的充放电电流 支持4LED指示灯
c语言·开发语言·单片机
曼巴UE56 小时前
UE5.3 C++ 接口初步使用
开发语言·jvm·c++
奔跑的石头_6 小时前
GO语言的主要语法和特性
开发语言