mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 21:50:44 +00:00
琚帶绔?- 淇 MTU 闂锛氬す MSS + 璺緞 MTU 鎺㈡祴锛堝叕缃戝彲鐢ㄧ巼 48% -> 100%锛?- 澶嶇敤 HTTP 杩炴帴锛堝厤鎺夋瘡娆℃柊寤?TLS 鐨?30% 鎻℃墜澶辫触锛?- 姣忓垎閽熷洖澶存壘灞€鍩熺綉锛岃嚜鍔ㄥ垏鍥炲揩 400 鍊嶇殑璺緞 - 鐢婚潰蹇冭烦甯э細闈欐鏃剁渷娴侀噺锛屽鎴风浠嶇煡閬撴祦鏄椿鐨?- 閿佸睆鏃剁粰鍑哄彲鎿嶄綔鐨勬彁绀? 鎵嬭〃绔?- 鍐呯疆 GTS Root R4 / GlobalSign Root CA锛屼慨 SSLHandshakeException - 杩炴帴閿欒缈昏瘧鎴愪汉璇濓紙璇佷功/鏃堕棿/瑙f瀽/瓒呮椂鍒嗗埆鎻愮ず锛?- 缁忎腑杞繛涓婂悗鐢ㄦ湇鍔″櫒鎶ョ殑鍦板潃鍒锋柊宸查厤瀵硅褰?- 鏂板灞€鍩熺綉杩炴帴椤甸潰銆佹湇鍔″櫒寤惰繜妫€娴? 鏈嶅姟鍣ㄧ - 鏀寔 chunked 璇锋眰浣擄紙淇瘡 16 绉掍竴娆$殑杩炴帴閿欎贡涓庡ぇ闈㈢Н 502锛?- 缃戠粶璋冧紭鑴氭湰 net-tune.sh锛堝紑鏈鸿嚜鍔ㄥ簲鐢級 - 绠$悊椤碉細鎵归噺鍒犻櫎銆佺綉缁滀綋妫€銆佷笅杞藉尯 - 闅ч亾鏀?HTTP/2 + 鍙岃繛鎺? 鏂囨。 - 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
206 lines
8.1 KiB
Python
206 lines
8.1 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""应用内网络自检(原来是一个独立的控制台脚本,现在做进界面里)。
|
||
|
||
和独立脚本最大的区别:
|
||
被控端自己就在监听 8765/8766,所以**不需要再去绑端口**,
|
||
直接读它自己的计数器就知道手表的包有没有到:
|
||
* 自动发现请求收到几个
|
||
* TCP 连接来过几次
|
||
这比再开一个进程抢端口靠谱得多,也正是"连不上"时最想知道的事。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import os
|
||
import platform
|
||
import socket
|
||
import subprocess
|
||
import time
|
||
|
||
from .config import app_dir
|
||
from .discovery import DISCOVERY_PORT
|
||
from .firewall import check as firewall_check
|
||
|
||
_NO_WINDOW = getattr(subprocess, "CREATE_NO_WINDOW", 0)
|
||
|
||
|
||
def _run(cmd: list[str], timeout: int = 12) -> str:
|
||
try:
|
||
proc = subprocess.run(cmd, capture_output=True, timeout=timeout,
|
||
creationflags=_NO_WINDOW,
|
||
encoding="mbcs" if os.name == "nt" else "utf-8",
|
||
errors="replace")
|
||
return (proc.stdout or "") + (proc.stderr or "")
|
||
except Exception: # noqa: BLE001
|
||
return ""
|
||
|
||
|
||
def local_ips() -> list[tuple[str, str]]:
|
||
"""本机所有可用的局域网 IPv4。"""
|
||
out: list[tuple[str, str]] = []
|
||
try:
|
||
probe = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||
probe.connect(("8.8.8.8", 80))
|
||
addr = probe.getsockname()[0]
|
||
probe.close()
|
||
if addr and not addr.startswith("127."):
|
||
out.append((addr, "默认路由"))
|
||
except OSError:
|
||
pass
|
||
try:
|
||
for info in socket.getaddrinfo(socket.gethostname(), None, socket.AF_INET):
|
||
addr = info[4][0]
|
||
if addr and not addr.startswith("127.") and addr not in [a for a, _ in out]:
|
||
out.append((addr, "主机名"))
|
||
except OSError:
|
||
pass
|
||
return out
|
||
|
||
|
||
def wifi_name() -> str:
|
||
text = _run(["netsh", "wlan", "show", "interfaces"])
|
||
for raw in text.splitlines():
|
||
line = raw.strip()
|
||
if line.startswith("SSID") and "BSSID" not in line:
|
||
return line.split(":", 1)[-1].strip()
|
||
return ""
|
||
|
||
|
||
def collect(server, store) -> dict:
|
||
"""把自检需要的东西一次性收集出来。"""
|
||
data: dict = {
|
||
"time": time.strftime("%Y-%m-%d %H:%M:%S"),
|
||
"os": f"{platform.system()} {platform.release()}",
|
||
"ips": local_ips(),
|
||
"wifi": wifi_name(),
|
||
"port": getattr(server, "port", 0),
|
||
"discovery_port": DISCOVERY_PORT,
|
||
"server_running": bool(getattr(server, "running", False)),
|
||
"probes": 0,
|
||
"selfcheck_requests": 0,
|
||
"tcp_connections": 0,
|
||
"connected": [],
|
||
"firewall": {},
|
||
"app_dir": str(app_dir()),
|
||
}
|
||
|
||
# 服务端状态(含自动发现计数、累计 TCP 连接数)
|
||
try:
|
||
status = server.status()
|
||
data["connected"] = status.get("connected", [])
|
||
data["pairing_code"] = status.get("pairing_code", "")
|
||
data["screen_sharing"] = status.get("screen_sharing", False)
|
||
data["tcp_connections"] = int(status.get("total_connections", 0) or 0)
|
||
|
||
info = status.get("discovery") or {}
|
||
data["probes"] = int(info.get("answered", 0) or 0)
|
||
data["selfcheck_requests"] = int(info.get("selfcheck_requests", 0) or 0)
|
||
data["discovery_running"] = bool(info.get("running"))
|
||
data["discovery_error"] = info.get("error", "")
|
||
except Exception as exc: # noqa: BLE001
|
||
data["discovery_running"] = False
|
||
data["discovery_error"] = str(exc)
|
||
|
||
# 防火墙
|
||
try:
|
||
data["firewall"] = firewall_check(data["port"] or 8765, DISCOVERY_PORT)
|
||
except Exception as exc: # noqa: BLE001
|
||
data["firewall"] = {"supported": False, "message": str(exc)}
|
||
|
||
return data
|
||
|
||
|
||
def verdict(data: dict) -> tuple[str, str]:
|
||
"""给出结论:(级别, 文字)。级别是 ok / warn / error。"""
|
||
fw = data.get("firewall") or {}
|
||
if not data.get("server_running"):
|
||
return "error", "被控端没有在运行 —— 先启动它,否则手表一定连不上。"
|
||
|
||
if not fw.get("supported"):
|
||
return "warn", "防火墙状态读不到(可能不是 Windows),无法判断。"
|
||
|
||
if fw.get("blocked_count"):
|
||
return "error", (f"有 {fw['blocked_count']} 条「阻止」规则压着,"
|
||
"手表能搜到但连不上。去「设置/修复」点一键修复。")
|
||
|
||
if not (fw.get("tcp") and fw.get("udp")):
|
||
return "error", "端口放行规则缺失,其他设备连不上。点「一键修复」。"
|
||
|
||
if not fw.get("app_rule"):
|
||
return "warn", ("现在能连上,但程序级放行规则不完整,"
|
||
"以后系统可能再生成阻止规则。建议修一次。")
|
||
|
||
probes = data.get("probes", 0)
|
||
conns = data.get("tcp_connections", 0)
|
||
if probes == 0 and conns == 0:
|
||
return "warn", ("防火墙没问题,但**一个包都没收到**。"
|
||
"手表可能不在同一个 WiFi,或路由器开了 AP 隔离。")
|
||
|
||
return "ok", "一切正常,手表应该能连上。"
|
||
|
||
|
||
def render(data: dict) -> str:
|
||
"""把自检结果渲染成可复制的文本。"""
|
||
level, text = verdict(data)
|
||
lines: list[str] = []
|
||
lines.append("===== 电脑端自检 =====")
|
||
lines.append(f"时间: {data.get('time')}")
|
||
lines.append(f"系统: {data.get('os')}")
|
||
lines.append("")
|
||
|
||
lines.append("--- 本机网络 ---")
|
||
ips = data.get("ips") or []
|
||
if ips:
|
||
for addr, tag in ips:
|
||
lines.append(f" {addr} [{tag}]")
|
||
lines.append(f" >>> 手表上填这个 IP:{ips[0][0]}")
|
||
else:
|
||
lines.append(" 没读到 IP(网络没连上?)")
|
||
if data.get("wifi"):
|
||
lines.append(f" WiFi: {data['wifi']}")
|
||
lines.append("")
|
||
|
||
lines.append("--- 监听 ---")
|
||
lines.append(f" 控制端口 TCP {data.get('port')}: "
|
||
f"{'监听中' if data.get('server_running') else '未监听'}")
|
||
lines.append(f" 发现端口 UDP {data.get('discovery_port')}: "
|
||
f"{'监听中' if data.get('discovery_running') else '未监听'}")
|
||
if data.get("discovery_error"):
|
||
lines.append(f" 错误: {data['discovery_error']}")
|
||
lines.append("")
|
||
|
||
lines.append("--- 收到过多少(关键)---")
|
||
lines.append(f" 自动发现请求: {data.get('probes', 0)} 个")
|
||
lines.append(f" 自检请求: {data.get('selfcheck_requests', 0)} 个")
|
||
lines.append(f" TCP 连接: {data.get('tcp_connections', 0)} 次")
|
||
if data.get("probes", 0) == 0 and data.get("tcp_connections", 0) == 0:
|
||
lines.append(" !! 一直是 0 说明手表的包根本没到这台电脑")
|
||
else:
|
||
lines.append(" 有数字说明手表的包能到达这台电脑")
|
||
lines.append("")
|
||
|
||
lines.append("--- 防火墙 ---")
|
||
fw = data.get("firewall") or {}
|
||
lines.append(f" 端口放行 TCP: {'是' if fw.get('tcp') else '否'}")
|
||
lines.append(f" 端口放行 UDP: {'是' if fw.get('udp') else '否'}")
|
||
lines.append(f" 程序级放行: {'是' if fw.get('app_rule') else '否'} "
|
||
f"({os.path.basename(str(fw.get('app_rule_program') or '')) or '-'})")
|
||
lines.append(f" 阻止规则: {fw.get('blocked_count', 0)} 条(针对本程序)")
|
||
if fw.get("blocked_others"):
|
||
lines.append(f" 另外还有 {fw['blocked_others']} 条是针对别的程序的,不影响")
|
||
lines.append("")
|
||
|
||
lines.append("--- 已连接设备 ---")
|
||
connected = data.get("connected") or []
|
||
if connected:
|
||
for item in connected:
|
||
lines.append(f" {item.get('name', '?')} {item.get('addr', '')}")
|
||
else:
|
||
lines.append(" (没有设备连着)")
|
||
lines.append("")
|
||
|
||
lines.append("--- 结论 ---")
|
||
lines.append(f" [{level.upper()}] {text}")
|
||
lines.append("")
|
||
lines.append("===== 结束 =====")
|
||
return "\n".join(lines)
|