mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-19 13:00:44 +00:00
被控端 - 修复 MTU 问题:夹 MSS + 路径 MTU 探测(公网可用率 48% -> 100%) - 复用 HTTP 连接(免掉每次新建 TLS 的 30% 握手失败) - 每分钟回头找局域网,自动切回快 400 倍的路径 - 画面心跳帧:静止时省流量,客户端仍知道流是活的 - 锁屏时给出可操作的提示 手表端 - 内置 GTS Root R4 / GlobalSign Root CA,修 SSLHandshakeException - 连接错误翻译成人话(证书/时间/解析/超时分别提示) - 经中转连上后用服务器报的地址刷新已配对记录 - 新增局域网连接页面、服务器延迟检测 服务器端 - 支持 chunked 请求体(修每 16 秒一次的连接错乱与大面积 502) - 网络调优脚本 net-tune.sh(开机自动应用) - 管理页:批量删除、网络体检、下载区 - 隧道改 HTTP/2 + 双连接 文档 - 许可协议 / 安装前必读 / 安装后须知(作者:小麦子)
89 lines
2.5 KiB
Java
89 lines
2.5 KiB
Java
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();
|
|
}
|
|
}
|
|
}
|