mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-19 10:40:44 +00:00
ykxmz 1.5.0锛氫慨澶嶆墜琛ㄧ TLS 璇佷功鏍¢獙 + MTU 淇缃戠粶绋冲畾鎬?
琚帶绔?- 淇 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 + 鍙岃繛鎺? 鏂囨。 - 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
# -*- 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())
|
||||
Reference in New Issue
Block a user