hostthread.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include "hostthread.h"
  2. #include "qdebug.h"
  3. #include "qjsonarray.h"
  4. #include "qjsonobject.h"
  5. #include <QFile>
  6. #include <QProcess>
  7. #include <QRegularExpression>
  8. #include <QString>
  9. #include <QTextStream>
  10. #include <api/hostsapi.h>
  11. /*
  12. # Copyright (c) 1993-2009 Microsoft Corp.
  13. #
  14. # This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
  15. #
  16. # This file contains the mappings of IP addresses to host names. Each
  17. # entry should be kept on an individual line. The IP address should
  18. # be placed in the first column followed by the corresponding host name.
  19. # The IP address and the host name should be separated by at least one
  20. # space.
  21. #
  22. # Additionally, comments (such as these) may be inserted on individual
  23. # lines or following the machine name denoted by a '#' symbol.
  24. #
  25. # For example:
  26. #
  27. # 102.54.94.97 rhino.acme.com # source server
  28. # 38.25.63.10 x.acme.com # x client host
  29. # localhost name resolution is handled within DNS itself.
  30. # 127.0.0.1 localhost
  31. # ::1 localhost
  32. 127.0.0.1 activate.navicat.com
  33. 127.0.0.1 example.com
  34. */
  35. static void ipconfigFlushdns()
  36. {
  37. // 创建 QProcess 对象
  38. QProcess process;
  39. // 设置要执行的命令和参数
  40. process.start("ipconfig", QStringList() << "/flushdns");
  41. // 等待命令执行完成
  42. process.waitForFinished();
  43. // 获取命令输出(如果有的话)
  44. auto output = process.readAllStandardOutput();
  45. auto errorOutput = process.readAllStandardError();
  46. // 输出结果
  47. if (!output.isEmpty()) {
  48. qDebug() << "Command output:" << QString::fromLocal8Bit(output);
  49. }
  50. if (!errorOutput.isEmpty()) {
  51. qDebug() << "Command error:" << errorOutput;
  52. }
  53. }
  54. static bool modifyHostsFile(const QString &hostname, const QString &ipAddress, bool action)
  55. {
  56. QString hostsFilePath;
  57. #ifdef Q_OS_WIN
  58. hostsFilePath = "C:/Windows/System32/drivers/etc/hosts";
  59. #else
  60. hostsFilePath = "/etc/hosts";
  61. #endif
  62. // 打开hosts文件
  63. QFile file(hostsFilePath);
  64. if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
  65. qWarning() << "无法打开文件" << hostsFilePath;
  66. return false;
  67. }
  68. // 读取文件内容
  69. QTextStream stream(&file);
  70. QStringList fileLines;
  71. QRegularExpression regex(
  72. R"RX(^(#?\s*)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([a-zA-Z0-9.-]+)(\s+#.*)?$)RX");
  73. bool isExist = false;
  74. while (!stream.atEnd()) {
  75. QString line = stream.readLine(); // 读取一行
  76. fileLines.append(line); // 保存当前行
  77. QRegularExpressionMatch expressionMatch = regex.match(line);
  78. if (expressionMatch.hasMatch()) {
  79. const QString url = expressionMatch.captured(3);
  80. if (url.compare(hostname) == 0) {
  81. if (action) { // 添加
  82. qDebug() << "---------------add" << url;
  83. qDebug() << "已存在,进行添加操作: " << url;
  84. fileLines.removeOne(line);
  85. } else {
  86. qDebug() << "---------------remove" << url;
  87. qDebug() << "删除操作: " << url;
  88. fileLines.removeOne(line);
  89. }
  90. }
  91. }
  92. }
  93. // 如果是添加操作并且记录不存在,添加新条目
  94. if (!isExist && action) {
  95. QString newLine = QString("%1 %2").arg(ipAddress).arg(hostname);
  96. fileLines.append(newLine); // 将新的条目添加到文件末尾
  97. qDebug() << "添加新的条目: " << newLine;
  98. }
  99. // 重写文件内容
  100. file.resize(0); // 清空文件内容
  101. QTextStream out(&file);
  102. for (const QString &line : fileLines) {
  103. out << line << "\n";
  104. }
  105. file.close();
  106. ipconfigFlushdns();
  107. return true;
  108. }
  109. // HostThread::HostThread()
  110. // {
  111. // if (modifyHostsFile("example.com", "127.0.0.1")) {
  112. // qDebug() << "Hosts 文件已成功更新。";
  113. // } else {
  114. // qDebug() << "修改失败。";
  115. // }
  116. // }
  117. HostThread::HostThread(QObject *parent) {}
  118. void HostThread::upDataHost()
  119. {
  120. TC::HostsApi hostsApi;
  121. const auto serverArray = hostsApi.get();
  122. QSet<QString> addressSet; // 添加
  123. QSet<QString> removeAddressSet; // 取消
  124. for (const QJsonValue &item : serverArray) {
  125. if (!item.isObject()) {
  126. return;
  127. }
  128. const QJsonObject object = item.toObject();
  129. const QString name = object["address"].toString();
  130. if (object.contains("value")) {
  131. if (object["value"].toString() == "-1" || object["value"].toInt() == -1) {
  132. addressSet.insert(name);
  133. modifyHostsFile(name, "127.0.0.1", true);
  134. } else {
  135. removeAddressSet.insert(name);
  136. modifyHostsFile(name, "127.0.0.1", false);
  137. }
  138. }
  139. }
  140. // if (modifyHostsFile("example.com", "127.0.0.1", true)) {
  141. // qDebug() << "Hosts 文件已成功更新。";
  142. // } else {
  143. // qDebug() << "修改失败。";
  144. // }
  145. }
  146. void HostThread::run()
  147. {
  148. QElapsedTimer timer; // 创建高精度计时器
  149. timer.start(); // 启动计时器
  150. upDataHost();
  151. while (true) {
  152. // 校验网络
  153. if (timer.elapsed() >= 30 * 1000) {
  154. timer.restart();
  155. upDataHost();
  156. }
  157. msleep(1000); // 休息1秒
  158. }
  159. }