# -*- coding: utf-8 -*- r"""诊断:发现端口 8766 到底有没有被 agent 绑上。 test_selfcheck 广播到 127.0.0.1:8766 收到 WSAECONNRESET(ICMP 端口不可达), 说明**没有进程在监听 8766**。但测试里 agent 明明起来了(8841 能连)。 查清楚是: a) agent 绑 8766 失败(被占 / 权限) b) agent 压根没去绑 c) 绑上了但没回包 """ from __future__ import annotations import os import shutil import socket import subprocess import sys import time from pathlib import Path ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote") PORT = 8851 DISCOVERY = 8766 def port_holder(port: int, udp: bool) -> list[str]: out: list[str] = [] if udp: cmd = ("Get-NetUDPEndpoint -LocalPort %d -ErrorAction SilentlyContinue | " "ForEach-Object { \"$($_.LocalAddress):$($_.LocalPort) PID $($_.OwningProcess)\" }" % port) else: cmd = ("Get-NetTCPConnection -LocalPort %d -ErrorAction SilentlyContinue | " "ForEach-Object { \"$($_.LocalAddress):$($_.LocalPort) PID $($_.OwningProcess)\" }" % port) proc = subprocess.run(["powershell", "-NoProfile", "-Command", cmd], capture_output=True, text=True, timeout=30) for line in (proc.stdout or "").splitlines(): if line.strip(): out.append(line.strip()) return out def main() -> int: # 清干净(注意别把自己杀了 —— $PID 在 PowerShell 里是 PowerShell 的, # 所以这里按命令行特征挑,不用 PID 比较) subprocess.run( ["powershell", "-NoProfile", "-Command", "Get-CimInstance Win32_Process -Filter \"Name='python.exe'\" | " "Where-Object { $_.CommandLine -match 'run_agent' -or " "$_.CommandLine -match 'test_' } | " "ForEach-Object { Stop-Process -Id $_.ProcessId -Force " "-ErrorAction SilentlyContinue }"], capture_output=True, text=True, timeout=60) time.sleep(2) print(" 起之前,8766 有没有人占:") holders = port_holder(DISCOVERY, udp=True) print(f" {holders if holders else '空闲'}") data_dir = ROOT / "windows" / "data" if data_dir.exists(): shutil.rmtree(data_dir, ignore_errors=True) env = dict(os.environ) env["PYTHONIOENCODING"] = "utf-8" print() print(f" 起 agent(TCP {PORT})…") proc = subprocess.Popen( [sys.executable, "run_agent.py", "--port", str(PORT), "--new-code", "--add-device", "10"], cwd=str(ROOT / "windows"), env=env, stdout=open(ROOT / "_build" / "agent_diag.log", "wb"), stderr=subprocess.STDOUT) try: # 等 TCP 就绪 ready = False for _ in range(50): try: s = socket.create_connection(("127.0.0.1", PORT), timeout=1) s.close() ready = True break except OSError: time.sleep(0.4) print(f" TCP {PORT} 就绪: {ready}") time.sleep(1.5) print() print(f" 起之后,8766 有没有人占:") holders = port_holder(DISCOVERY, udp=True) print(f" {holders if holders else '还是空闲 —— 说明 agent 没绑上!'}") print() print(" 直接探测 8766:") sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(3) import json request = json.dumps({"lanremote": "LANREMOTE_SELFCHECK", "proto": 1}).encode("utf-8") try: sock.sendto(request, ("127.0.0.1", DISCOVERY)) data, addr = sock.recvfrom(2048) print(f" ✓ 收到应答: {data[:160]!r}") except ConnectionResetError as exc: print(f" ✗ WSAECONNRESET —— 端口不可达,没人监听({exc})") except socket.timeout: print(" ✗ 超时 —— 有人监听但没回") finally: sock.close() print() print(" agent 日志尾部:") log = ROOT / "_build" / "agent_diag.log" if log.is_file(): text = log.read_text(encoding="utf-8", errors="replace") for line in text.splitlines()[-14:]: print(f" {line}") finally: proc.terminate() try: proc.wait(timeout=10) except subprocess.TimeoutExpired: proc.kill() return 0 if __name__ == "__main__": sys.exit(main())