From a3c3d670e7391b98e23bc262cba0cec1a05a9d73 Mon Sep 17 00:00:00 2001 From: qsc20001102 Date: Fri, 31 Oct 2025 18:38:56 +0800 Subject: [PATCH] 15 --- app.log | 20 ++ .../__pycache__/network_fun.cpython-313.pyc | Bin 0 -> 4658 bytes core/Function/network_fun.py | 87 +++++++ .../__pycache__/tab_network.cpython-313.pyc | Bin 0 -> 18795 bytes .../ui/__pycache__/tab_telnet.cpython-313.pyc | Bin 9612 -> 9612 bytes core/ui/__pycache__/ui_main.cpython-313.pyc | Bin 1714 -> 1845 bytes core/ui/tab_network.py | 230 ++++++++++++++++++ core/ui/ui_main.py | 2 + 8 files changed, 339 insertions(+) create mode 100644 core/Function/__pycache__/network_fun.cpython-313.pyc create mode 100644 core/Function/network_fun.py create mode 100644 core/ui/__pycache__/tab_network.cpython-313.pyc create mode 100644 core/ui/tab_network.py diff --git a/app.log b/app.log index 549e7d3..193fca3 100644 --- a/app.log +++ b/app.log @@ -302,3 +302,23 @@ 2025-10-31 17:26:41,880 [INFO] 开始测试202.89.233.100 的 [21, 22, 23, 25, 80, 110, 143, 443, 1433, 3306, 3389] 端口连接情况 2025-10-31 17:26:43,350 [INFO] 开始测试202.89.233.100 的 100 到 1000 端口连接情况 2025-10-31 17:26:44,697 [INFO] 开始测试202.89.233.100 的 [21, 22, 23, 25, 80, 110, 143, 443, 1433, 3306, 3389] 端口连接情况 +2025-10-31 17:31:04,578 [INFO] 开始由 Ping www.feixiangdayezhu.top +2025-10-31 17:31:08,822 [INFO] 停止由 Ping www.feixiangdayezhu.top +2025-10-31 17:31:14,152 [INFO] 测试43.251.226.76 的 443 端口连接情况 +2025-10-31 17:31:39,432 [INFO] 开始测试43.251.226.76 的 [21, 22, 23, 25, 80, 110, 143, 443, 1433, 3306, 3389] 端口连接情况 +2025-10-31 17:31:54,044 [INFO] 开始测试43.251.226.76 的 5000 到 6000 端口连接情况 +2025-10-31 17:33:19,351 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 17:33:23,076 [INFO] 测试202.89.233.100 的 443 端口连接情况 +2025-10-31 17:33:25,235 [INFO] 开始测试202.89.233.100 的 [21, 22, 23, 25, 80, 110, 143, 443, 1433, 3306, 3389] 端口连接情况 +2025-10-31 17:33:28,400 [INFO] 开始测试202.89.233.100 的 100 到 1000 端口连接情况 +2025-10-31 17:54:18,741 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 17:55:53,064 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 17:57:20,180 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 17:58:58,242 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 17:59:44,536 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 18:01:39,713 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 18:10:28,190 [INFO] 测试202.89.233.100 的 443 端口连接情况 +2025-10-31 18:17:02,500 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 18:20:28,569 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 18:21:50,145 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 18:33:44,665 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log diff --git a/core/Function/__pycache__/network_fun.cpython-313.pyc b/core/Function/__pycache__/network_fun.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86dd5432f8ec4baa4ea805c9648b38a07f64d396 GIT binary patch literal 4658 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≧0# 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 diff --git a/core/ui/tab_network.py b/core/ui/tab_network.py new file mode 100644 index 0000000..99a2585 --- /dev/null +++ b/core/ui/tab_network.py @@ -0,0 +1,230 @@ +import tkinter as tk +from tkinter import ttk, messagebox, scrolledtext +import threading +import logging + +from core.ui.basic_ui import BasicUI +from core.Function.network_fun import NetworkManager + +logger = logging.getLogger(__name__) + +class NetworkTab(ttk.Frame, BasicUI): + """网卡配置 Tab(兼容最新 NetworkManager)""" + + def __init__(self, parent): + super().__init__(parent) + self.netmgr = NetworkManager() + self._build_ui() + threading.Thread(target=self.refresh_interfaces, daemon=True).start() + + # ---------------- UI 构建 ---------------- + def _build_ui(self): + self.create_iface_section() + self.create_config_section() + self.create_action_section() + self.create_output_section() + self._set_button_state(enabled=True) + + def create_iface_section(self): + frame = ttk.LabelFrame(self, text="网卡选择", padding=8) + frame.pack(side='top', fill='x', padx=10, pady=6) + + self.iface_var = tk.StringVar() + ttk.Label(frame, text="选择网卡:").grid(row=0, column=0, sticky='w') + self.iface_cb = ttk.Combobox(frame, textvariable=self.iface_var, state='readonly', width=40) + self.iface_cb.grid(row=0, column=1, padx=6, pady=2) + self.iface_cb.bind("<>", self.on_iface_selected) + + self.refresh_btn = ttk.Button(frame, text="刷新", width=10, command=self.on_refresh_clicked) + self.refresh_btn.grid(row=0, column=2, padx=6) + + def create_config_section(self): + frame = ttk.LabelFrame(self, text="IP 配置(编辑后点击应用)", padding=8) + frame.pack(side='top', fill='x', padx=10, pady=6) + + self.ip_entry = self.add_input(frame, "IPv4 地址", row=0, col=0, inivar="", entry_width=25) + self.mask_entry = self.add_input(frame, "子网掩码", row=0, col=1, inivar="", entry_width=20) + self.gw_entry = self.add_input(frame, "默认网关", row=1, col=0, inivar="", entry_width=25) + self.dns1_entry = self.add_input(frame, "主 DNS", row=1, col=1, inivar="", entry_width=25) + self.dns2_entry = self.add_input(frame, "备选 DNS", row=1, col=2, inivar="", entry_width=25) + + self.dhcp_var = tk.BooleanVar(value=False) + self.dhcp_chk = ttk.Checkbutton(frame, text="使用 DHCP(自动获取 IP)", variable=self.dhcp_var, + command=self.on_dhcp_toggled) + self.dhcp_chk.grid(row=2, column=0, columnspan=2, sticky='w', pady=6) + + def create_action_section(self): + frame = ttk.Frame(self) + frame.pack(side='top', fill='x', padx=10, pady=6) + self.apply_btn = self.add_button(frame, "应用修改", row=0, col=0, command=self.on_apply_clicked) + self.dhcp_btn = self.add_button(frame, "切换为 DHCP", row=0, col=1, command=self.on_set_dhcp) + self.refresh_info_btn = self.add_button(frame, "刷新当前信息", row=0, col=2, command=self.on_refresh_info) + + def create_output_section(self): + frame = ttk.LabelFrame(self, text="操作日志", padding=6) + frame.pack(side='top', fill='both', expand=True, padx=10, pady=6) + self.result_box = scrolledtext.ScrolledText(frame, width=100, height=12) + self.result_box.pack(fill='both', expand=True, padx=4, pady=4) + + def _set_button_state(self, enabled: bool): + state = 'normal' if enabled else 'disabled' + for btn in [self.apply_btn, self.dhcp_btn, self.refresh_info_btn, self.refresh_btn]: + try: + btn.config(state=state) + except Exception: + pass + + # ---------------- 事件回调 ---------------- + def on_refresh_clicked(self): + self._append_log("刷新网卡列表中...\n") + threading.Thread(target=self.refresh_interfaces, daemon=True).start() + + def refresh_interfaces(self): + try: + adapters = self.netmgr.get_all_adapters() + except Exception as e: + self._append_log(f"获取网卡失败: {e}\n") + return + + names = [a.get("name") or a.get("desc") or str(i) for i, a in enumerate(adapters)] + + def update_ui(): + self._adapters = adapters + self.iface_cb['values'] = names + if names: + self.iface_var.set(names[0]) + self.load_selected_adapter_info(names[0]) + self.after(0, update_ui) + self._append_log("网卡列表刷新完成。\n") + + def on_iface_selected(self, event=None): + name = self.iface_var.get() + self.load_selected_adapter_info(name) + + def load_selected_adapter_info(self, name): + adapter = next((a for a in getattr(self, "_adapters", []) if a.get("name")==name or a.get("desc")==name), None) + if not adapter: + self._append_log(f"未找到网卡信息:{name}\n") + return + + try: + self.ip_entry['var'].set(adapter.get("ip", "")) + self.mask_entry['var'].set(adapter.get("mask", "")) + self.gw_entry['var'].set(adapter.get("gateway", "")) + self.dns1_entry['var'].set(adapter.get("dns1", "")) + self.dns2_entry['var'].set(adapter.get("dns2", "")) + except Exception: + pass + + self.dhcp_var.set(True if str(adapter.get("dhcp", "")).lower() in ("yes","true","是") else False) + self._append_log(f"已加载网卡:{name} IP={adapter.get('ip')} 掩码={adapter.get('mask')} 网关={adapter.get('gateway')} DHCP={adapter.get('dhcp')} MAC={adapter.get('mac')}\n") + + def on_dhcp_toggled(self): + use_dhcp = self.dhcp_var.get() + state = 'disabled' if use_dhcp else 'normal' + for entry in [self.ip_entry, self.mask_entry, self.gw_entry]: + try: + entry['entry'].config(state=state) + except Exception: + try: + entry.config(state=state) + except Exception: + pass + + def on_refresh_info(self): + name = self.iface_var.get() + if not name: + messagebox.showwarning("提示", "请先选择一个网卡") + return + self._append_log(f"读取 {name} 的当前配置信息...\n") + threading.Thread(target=self._refresh_info_thread, args=(name,), daemon=True).start() + + def _refresh_info_thread(self, name): + try: + adapters = self.netmgr.get_all_adapters() + self._adapters = adapters + for a in adapters: + if a.get("name")==name or a.get("desc")==name: + self.after(0, lambda ad=a: self.load_selected_adapter_info(ad.get("name"))) + break + self._append_log("刷新完成。\n") + except Exception as e: + self._append_log(f"读取配置失败: {e}\n") + + def on_apply_clicked(self): + name = self.iface_var.get() + if not name: + messagebox.showwarning("提示", "请选择一个网卡") + return + + def read_field(field): + try: return field['var'].get().strip() + except Exception: + try: return field.get().strip() + except Exception: return "" + + ip = read_field(self.ip_entry) + mask = read_field(self.mask_entry) + gw = read_field(self.gw_entry) + dns1 = read_field(self.dns1_entry) + dns2 = read_field(self.dns2_entry) + + if self.dhcp_var.get(): + if not messagebox.askyesno("确认", f"确定将网卡 [{name}] 切换为 DHCP 模式吗?"): + return + self._set_button_state(False) + threading.Thread(target=self._set_dhcp_thread, args=(name,), daemon=True).start() + return + + if not ip or not mask: + messagebox.showwarning("输入错误", "IP 与掩码不能为空(或勾选 DHCP)") + return + + self._set_button_state(False) + threading.Thread(target=self._set_static_thread, args=(name, ip, mask, gw, dns1, dns2), daemon=True).start() + + def _set_dhcp_thread(self, name): + try: + res = self.netmgr.set_dhcp(name) + self._append_log(f"{res}\n") + messagebox.showinfo("完成", res) + threading.Thread(target=self.refresh_interfaces, daemon=True).start() + except Exception as e: + self._append_log(f"设置 DHCP 失败: {e}\n") + messagebox.showerror("失败", f"设置 DHCP 失败: {e}") + finally: + self._set_button_state(True) + + def _set_static_thread(self, name, ip, mask, gw, dns1, dns2): + try: + res = self.netmgr.set_static_ip(name, ip, mask, gw) + self._append_log(f"{res}\n") + if dns1: + try: + res_dns = self.netmgr.set_dns(name, dns1, dns2) + self._append_log(f"{res_dns}\n") + except Exception as e: + self._append_log(f"设置 DNS 失败: {e}\n") + messagebox.showinfo("完成", "配置已应用(请注意可能需要管理员权限)") + threading.Thread(target=self.refresh_interfaces, daemon=True).start() + except Exception as e: + self._append_log(f"应用静态 IP 失败: {e}\n") + messagebox.showerror("失败", f"应用静态 IP 失败: {e}") + finally: + self._set_button_state(True) + + def on_set_dhcp(self): + name = self.iface_var.get() + if not name: + messagebox.showwarning("提示", "请选择一个网卡") + return + if not messagebox.askyesno("确认", f"确定将网卡 [{name}] 切换为 DHCP 模式吗?"): + return + self._set_button_state(False) + threading.Thread(target=self._set_dhcp_thread, args=(name,), daemon=True).start() + + def _append_log(self, text: str): + try: + self.result_box.after(0, lambda: (self.result_box.insert(tk.END, text), self.result_box.see(tk.END))) + except Exception: + pass diff --git a/core/ui/ui_main.py b/core/ui/ui_main.py index dae6307..539c8ae 100644 --- a/core/ui/ui_main.py +++ b/core/ui/ui_main.py @@ -4,6 +4,7 @@ from tkinter import ttk, filedialog, messagebox from core.ui.basic_ui import BasicUI from core.ui.tab_ping import PingTab from core.ui.tab_telnet import TelnetTab +from core.ui.tab_network import NetworkTab import logging logger = logging.getLogger(__name__) @@ -19,6 +20,7 @@ class MainUI(BasicUI): self.tab_control.pack(expand=1, fill="both") # 实例化各个功能页 self.tabs = { + "网卡配置": NetworkTab(self.tab_control), "Ping测试": PingTab(self.tab_control), "端口扫描服务端": TelnetTab(self.tab_control), }