mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 14:50:45 +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 + 鍙岃繛鎺? 鏂囨。 - 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
232 lines
8.0 KiB
Python
232 lines
8.0 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""让 RemoteClient 支持中转(跨网络)。
|
||
|
||
改动很小,因为把"怎么传字节"抽成了 Transport:
|
||
SocketTransport —— 原来的局域网直连
|
||
RelayTransport —— 走中转服务器
|
||
|
||
RemoteClient 里协议相关的代码(readLoop / call / awaitReply / send)
|
||
一行都不用动。
|
||
|
||
新增 connectViaRelay(baseUrl, code, token, listener, timeout):
|
||
和原有 connect(host, port, ...) 走同一套握手流程。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote")
|
||
CLIENT = ROOT / "android" / "src" / "com" / "lanremote" / "watch" / "RemoteClient.java"
|
||
JSON = ROOT / "android" / "src" / "com" / "lanremote" / "watch" / "Json.java"
|
||
|
||
# ---------------- 1. Json.escape ----------------
|
||
|
||
JSON_ANCHOR = " public static String write(Object value) {"
|
||
|
||
JSON_NEW = ''' /**
|
||
* 把字符串转义成能安全塞进 JSON 字符串字面量的形式。
|
||
* 只处理引号、反斜杠和控制字符 —— 中文不用转,JSON 本身是 UTF-8。
|
||
*/
|
||
public static String escape(String text) {
|
||
if (text == null) {
|
||
return "";
|
||
}
|
||
StringBuilder out = new StringBuilder(text.length() + 16);
|
||
for (int i = 0; i < text.length(); i++) {
|
||
char ch = text.charAt(i);
|
||
switch (ch) {
|
||
case '"':
|
||
out.append("\\\\\\"");
|
||
break;
|
||
case '\\\\':
|
||
out.append("\\\\\\\\");
|
||
break;
|
||
case '\\n':
|
||
out.append("\\\\n");
|
||
break;
|
||
case '\\r':
|
||
out.append("\\\\r");
|
||
break;
|
||
case '\\t':
|
||
out.append("\\\\t");
|
||
break;
|
||
default:
|
||
if (ch < 0x20) {
|
||
out.append(String.format("\\\\u%04x", (int) ch));
|
||
} else {
|
||
out.append(ch);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return out.toString();
|
||
}
|
||
|
||
''' + JSON_ANCHOR
|
||
|
||
# ---------------- 2. RemoteClient ----------------
|
||
|
||
FIELD_OLD = ''' private Socket socket;
|
||
private BufferedReader reader;'''
|
||
|
||
FIELD_NEW = ''' /**
|
||
* 传输层。局域网直连时是 SocketTransport,跨网络时是 RelayTransport。
|
||
* 抽出来之后协议逻辑完全不用管数据是走 TCP 还是走中转的 HTTPS。
|
||
*/
|
||
private Transport transport;
|
||
private BufferedReader reader;'''
|
||
|
||
CONNECTED_OLD = ''' public boolean isConnected() {
|
||
return running && socket != null && !socket.isClosed();
|
||
}'''
|
||
|
||
CONNECTED_NEW = ''' public boolean isConnected() {
|
||
return running && transport != null && !transport.isClosed();
|
||
}
|
||
|
||
/** 当前传输方式的描述,界面上用来显示"直连"还是"经中转"。 */
|
||
public String transportName() {
|
||
if (transport == null) {
|
||
return "";
|
||
}
|
||
return transport instanceof RelayTransport ? "中转" : "直连";
|
||
}
|
||
|
||
public RelayTransport relayTransport() {
|
||
return transport instanceof RelayTransport
|
||
? (RelayTransport) transport : null;
|
||
}'''
|
||
|
||
CONNECT_OLD = ''' Socket sock = new Socket();
|
||
sock.connect(new InetSocketAddress(host, port), timeoutMs);
|
||
sock.setSoTimeout(0);
|
||
sock.setTcpNoDelay(true);
|
||
this.socket = sock;
|
||
this.reader = new BufferedReader(new InputStreamReader(sock.getInputStream(), UTF8), 8192);
|
||
this.writer = sock.getOutputStream();
|
||
|
||
Thread thread = new Thread(new Runnable() {'''
|
||
|
||
CONNECT_NEW = ''' Socket sock = new Socket();
|
||
sock.connect(new InetSocketAddress(host, port), timeoutMs);
|
||
sock.setSoTimeout(0);
|
||
sock.setTcpNoDelay(true);
|
||
return startTransport(new Transport.SocketTransport(sock), code, token,
|
||
listener, timeoutMs);
|
||
}
|
||
|
||
/**
|
||
* 经中转服务器连接(跨网络)。
|
||
*
|
||
* 手表没法直连电脑(两边都在 NAT 后面),所以两边都主动连出去,
|
||
* 由中转按配对码把两条连接对上。中转只转发字节、不认识协议内容,
|
||
* 所以电脑那边的配对和令牌校验照样生效。
|
||
*/
|
||
public Map<String, Object> connectViaRelay(String baseUrl, String code,
|
||
String token, Listener listener,
|
||
int timeoutMs) throws IOException {
|
||
close();
|
||
RelayTransport relay = new RelayTransport(baseUrl, code, deviceName);
|
||
if (!relay.attach()) {
|
||
String reason = relay.getLastError();
|
||
relay.close();
|
||
throw new IOException(reason == null || reason.isEmpty()
|
||
? "连不上中转服务器" : reason);
|
||
}
|
||
return startTransport(relay, code, token, listener, timeoutMs);
|
||
}
|
||
|
||
/** 握手 + 起读取线程。局域网和中转共用这一段。 */
|
||
private Map<String, Object> startTransport(Transport channel, String code,
|
||
String token, Listener listener,
|
||
int timeoutMs) throws IOException {
|
||
this.listener = listener;
|
||
this.running = true;
|
||
this.replies.clear();
|
||
this.transport = channel;
|
||
this.reader = new BufferedReader(
|
||
new InputStreamReader(channel.input(), UTF8), 8192);
|
||
this.writer = channel.output();
|
||
|
||
Thread thread = new Thread(new Runnable() {'''
|
||
|
||
CLOSE_OLD = ''' public void close() {
|
||
running = false;
|
||
try {
|
||
if (socket != null) {
|
||
socket.close();
|
||
}
|
||
} catch (IOException ignored) {
|
||
// 关闭时的异常无需处理
|
||
}
|
||
socket = null;
|
||
reader = null;
|
||
writer = null;
|
||
replies.clear();
|
||
}'''
|
||
|
||
CLOSE_NEW = ''' public void close() {
|
||
running = false;
|
||
try {
|
||
if (transport != null) {
|
||
transport.close();
|
||
}
|
||
} catch (Exception ignored) {
|
||
// 关闭时的异常无需处理
|
||
}
|
||
transport = null;
|
||
reader = null;
|
||
writer = null;
|
||
replies.clear();
|
||
}'''
|
||
|
||
|
||
def main() -> int:
|
||
ok = True
|
||
|
||
# ---- Json.escape ----
|
||
text = JSON.read_text(encoding="utf-8")
|
||
if "public static String escape(" in text:
|
||
print(" Json.escape 已存在")
|
||
elif JSON_ANCHOR not in text:
|
||
print(" [失败] Json 锚点没找到")
|
||
ok = False
|
||
else:
|
||
text = text.replace(JSON_ANCHOR, JSON_NEW, 1)
|
||
JSON.write_text(text, encoding="utf-8")
|
||
print(" Json.escape 已加")
|
||
|
||
# ---- RemoteClient ----
|
||
text = CLIENT.read_text(encoding="utf-8")
|
||
if "connectViaRelay" in text:
|
||
print(" RemoteClient 已经改过")
|
||
else:
|
||
for old, new, tag in ((FIELD_OLD, FIELD_NEW, "字段换成 Transport"),
|
||
(CONNECTED_OLD, CONNECTED_NEW, "isConnected 用 Transport"),
|
||
(CONNECT_OLD, CONNECT_NEW, "connect 拆出 startTransport + connectViaRelay"),
|
||
(CLOSE_OLD, CLOSE_NEW, "close 关 Transport")):
|
||
if old not in text:
|
||
print(f" [失败] {tag} —— 锚点没找到")
|
||
ok = False
|
||
continue
|
||
text = text.replace(old, new, 1)
|
||
print(f" {tag}")
|
||
CLIENT.write_text(text, encoding="utf-8")
|
||
|
||
# 检查还有没有裸用 socket 的地方
|
||
text = CLIENT.read_text(encoding="utf-8")
|
||
leftovers = [line.strip() for line in text.splitlines()
|
||
if "socket" in line and "Transport" not in line
|
||
and "Socket" not in line and "//" not in line]
|
||
if leftovers:
|
||
print(f" [注意] 还有裸用 socket 的行:{leftovers}")
|
||
else:
|
||
print(" 没有残留的裸 socket 引用")
|
||
|
||
return 0 if ok else 1
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|