ykxmz 1.5.0:修复手表端 TLS 证书校验 + MTU 修复网络稳定性

被控端
- 修复 MTU 问题:夹 MSS + 路径 MTU 探测(公网可用率 48% -> 100%)
- 复用 HTTP 连接(免掉每次新建 TLS 的 30% 握手失败)
- 每分钟回头找局域网,自动切回快 400 倍的路径
- 画面心跳帧:静止时省流量,客户端仍知道流是活的
- 锁屏时给出可操作的提示

手表端
- 内置 GTS Root R4 / GlobalSign Root CA,修 SSLHandshakeException
- 连接错误翻译成人话(证书/时间/解析/超时分别提示)
- 经中转连上后用服务器报的地址刷新已配对记录
- 新增局域网连接页面、服务器延迟检测

服务器端
- 支持 chunked 请求体(修每 16 秒一次的连接错乱与大面积 502)
- 网络调优脚本 net-tune.sh(开机自动应用)
- 管理页:批量删除、网络体检、下载区
- 隧道改 HTTP/2 + 双连接

文档
- 许可协议 / 安装前必读 / 安装后须知(作者:小麦子)
This commit is contained in:
xmz7891
2026-10-06 19:01:05 +08:00
commit b62ac865ea
3195 changed files with 203292 additions and 0 deletions
@@ -0,0 +1,88 @@
package com.lanremote.watch;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* RemoteClient 需要的传输层。
*
* 为什么要抽这一层:
* 原来 RemoteClient 直接用 Socket,只能在同一局域网里连。
* 跨网络时手表在 4G 上、电脑在 NAT 后面,直连不可能,
* 只能两边都主动连出去、由中转服务器对接。
* 把"怎么传字节"抽出来之后,RemoteClient 的协议逻辑一行都不用改:
* SocketTransport —— 原来的局域网直连
* RelayTransport —— 走中转服务器(HTTPS 长轮询)
*/
public interface Transport {
/** 来自对端的字节流。read() 应该阻塞等待。 */
InputStream input() throws IOException;
/** 发给对端的字节流。 */
OutputStream output() throws IOException;
/** 对端已经断开 / 自己关掉了。 */
boolean isClosed();
/** 关掉,释放资源。可以重复调用。 */
void close();
/** 显示用的对端描述("192.168.2.64:8765" 或 "中转服务器")。 */
String describe();
// ==================================================================
/** 局域网直连:就是原来的 Socket。 */
final class SocketTransport implements Transport {
private final Socket socket;
private final InputStream in;
private final OutputStream out;
private volatile boolean closed;
public SocketTransport(Socket socket) throws IOException {
this.socket = socket;
this.in = socket.getInputStream();
this.out = socket.getOutputStream();
}
public Socket socket() {
return socket;
}
@Override
public InputStream input() {
return in;
}
@Override
public OutputStream output() {
return out;
}
@Override
public boolean isClosed() {
return closed || socket.isClosed();
}
@Override
public void close() {
closed = true;
try {
socket.close();
} catch (IOException ignored) {
// 关的时候出错不用管
}
}
@Override
public String describe() {
return socket.getInetAddress() == null
? "电脑"
: socket.getInetAddress().getHostAddress() + ":"
+ socket.getPort();
}
}
}