diff --git a/core/device_discovery.py b/core/device_discovery.py index 60cde19..29ed1c3 100644 --- a/core/device_discovery.py +++ b/core/device_discovery.py @@ -114,17 +114,39 @@ def save_settings(enabled=None, subnets=None, interval=None, port=None): # ================== 网段展开与端口探测 ================== +def _local_ips(): + """本机自身 IP 集合(尽力而为):扫描时排除,避免探测到自己的 5555。 + + 优先 `hostname -I`(Linux/macOS 支持,一行空格分隔多 IP);不支持/失败的 + 平台退回 socket.getaddrinfo 枚举。关键:外部命令必须用 bytes 收——Windows + 上 git-bash 的 coreutils hostname 不支持 -I,会把 GBK 报错写进 stderr, + text=True 在 subprocess 后台读线程里 utf-8 严格解码会直接炸线程(主线程 + try/except 接不住异步线程异常)。 + """ + import subprocess + ips = set() + try: + r = subprocess.run(["hostname", "-I"], capture_output=True, timeout=3) + if r.returncode == 0: + ips.update(p for p in + r.stdout.decode("utf-8", errors="ignore").split() if p) + except Exception: + pass + if not ips: # 兜底:主机名解析出的接口 IPv4 + try: + for info in socket.getaddrinfo(socket.gethostname(), None): + ip = info[4][0] + if ":" not in ip: + ips.add(ip) + except Exception: + pass + return ips + + def _expand_subnets(subnets, max_hosts=_MAX_HOSTS_PER_SUBNET): """CIDR 列表 → IP 列表。排除 220 自身(USB_ADB_HOST)与本机 IP; 非法网段跳过记日志;单网段超过 max_hosts 截断并告警。""" - self_ips = {USB_ADB_HOST} - try: # 本机自身 IP(接口枚举,尽力而为;无 hostname -I 的平台跳过) - import subprocess - out = subprocess.run(["hostname", "-I"], capture_output=True, text=True, - timeout=3).stdout or "" - self_ips.update(p for p in out.split() if p) - except Exception: - pass + self_ips = {USB_ADB_HOST} | _local_ips() ips = [] for cidr in subnets: try: