#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