Skip to content

Commit 67536bb

Browse files
committed
feat: 1. 代码整理与优化 2. 更新README.md
1 parent 1799b16 commit 67536bb

File tree

3 files changed

+236
-155
lines changed

3 files changed

+236
-155
lines changed

README.md

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,27 @@
1919
<artifactId>vertx-core</artifactId>
2020
<version>4.5.10</version>
2121
</dependency>
22+
<!-- 若不使用http反向代理,可不加此依赖 -->
2223
<dependency>
2324
<groupId>io.vertx</groupId>
2425
<artifactId>vertx-web</artifactId>
2526
<version>4.5.10</version>
2627
</dependency>
28+
<!-- 若不想添加日志,可只添加slf4j-api -->
29+
<dependency>
30+
<groupId>ch.qos.logback</groupId>
31+
<artifactId>logback-classic</artifactId>
32+
<version>1.2.12</version>
33+
</dependency>
34+
<!-- 若不使用TCP内网穿透,可不加此依赖 -->
35+
<dependency>
36+
<groupId>com.google.protobuf</groupId>
37+
<artifactId>protobuf-javalite</artifactId>
38+
<version>4.30.2</version>
39+
</dependency>
2740
```
2841

29-
## TCP反向代理
42+
## 一、TCP反向代理
3043

3144
实现TCP反向代理:`0.0.0.0:22`↔️`10.0.0.1:8080`
3245

@@ -36,50 +49,83 @@ ReverseTcpProxy.create(Vertx.vertx(), "10.0.0.1", 8080)
3649
.start();
3750
```
3851

39-
## TCP内网穿透
40-
41-
实现表示建立连接/监听端口等等。
52+
## 二、TCP内网穿透
4253

43-
虚线表示连接通信
54+
虚线表示进程内部通信。实现表示外部通信
4455

4556
一些代码上的设计思路,参考[socket.io-client-java](https://github.com/socketio/socket.io-client-java/blob/socket.io-client-2.1.0/src/main/java/io/socket/client/Socket.java)
4657

4758
```mermaid
4859
sequenceDiagram
49-
participant user as User
60+
autonumber
61+
participant u as User
62+
participant dps as DataProxyServer
5063
participant ts as TunnelServer
5164
participant tc as TunnelClient
52-
participant rs as RealServer
65+
participant bs as BackendServer
5366
54-
ts->>ts: 1. 启动ts,监听tcp控制端口
55-
note left of ts: 明确tc与ts之间的编解码
56-
tc->>ts: 2. 建立控制连接,并进行认证
57-
ts-->>tc: 3. 控制连接:认证成功
58-
loop 控制连接实现长连接
59-
tc-->>ts: 控制连接:发送心跳
60-
ts-->>tc: 控制连接:响应心跳
67+
ts-->ts: 监听44444端口
68+
tc->>ts: 建立控制连接、发送鉴权密钥、申请启用22端口数据服务
69+
ts-->ts: 鉴权校验通过
70+
ts-->>dps: 你要开启22端口
71+
dps-->dps: 监听22端口
72+
dps-->>ts: 已开启
73+
ts->>tc: 成功
74+
tc-->tc: 开启与控制服务的周期心跳
75+
loop 控制连接保活
76+
tc->>ts: 发送心跳
77+
ts->>tc: 响应心跳
6178
end
62-
tc-->>ts: 4. 控制连接:要求ts监听数据传输端口。如2222端口
63-
ts->>ts: 5. 监听2222数据端口
64-
ts-->>tc: 6. 控制连接:已监听2222数据端口
65-
79+
u->>dps: 建立数据连接
80+
dps-->>ts: 通知
81+
ts->>tc: 你需要主动与22数据服务建立数据连接
82+
tc->>dps: 建立数据连接
83+
note left of dps: 用户连接和数据连接绑定双向生命周期、双向数据传输
84+
tc->>bs: 建立后端连接
85+
dps->>tc: 成功
86+
bs->>tc: 成功
87+
note right of tc: 数据连接和后端连接绑定双向生命周期、双向数据传输
88+
89+
u->dps: 双向传输
90+
dps->tc: 双向传输
91+
tc->bs: 双向传输
6692
67-
user->>ts: 7. 与2222端口建立用户连接,传输数据
68-
ts-->>tc: 8. 控制连接:有新的请求进来,需要你主动与我的2222端口建立数据连接
69-
tc->>ts: 9. 与2222端口建立数据连接
70-
tc-->>ts: 10. 控制连接:已建立
71-
ts->>ts: 11. 将连入2222端口的user用户连接和tc数据连接进行绑定
72-
note left of ts: 区分用户连接和数据连接
73-
ts-->>tc: 12. 数据连接:传输用户请求数据
74-
tc->>rs: 13. 请求真实服务
75-
rs-->>tc: 14. 服务响应
76-
tc-->>ts: 15. 数据连接:隧道响应
77-
ts-->user: 16. 返回最终结果
93+
94+
```
95+
96+
假如我有一个内网`SSH`服务`10.0.0.10:22`,需要通过`192.168.0.200:22`穿透出去。并且网络条件受限如下
97+
98+
1. `10.0.0.10`可以主动连接`192.168.0.200`
99+
2. `192.168.0.200`无法主动连接`10.0.0.10`
100+
3. 只要双方建立连接,即可实现双向数据传输
101+
102+
这就需要TCP内网穿透了。假设你内网穿透使用的控制端口为`44444`
103+
104+
首先,在`192.168.0.200`这台机器,使用如下代码启动`TunnelServer`
105+
106+
```java
107+
ReverseTcpProxyTunnelServer.create(Vertx.vertx())
108+
.port(44444)
109+
// 用于用户连接和数据连接的延迟判定,如果网络较差/DNS解析较慢的情况下,建议将该参数调大
110+
.judgeDelay(2000)
111+
.start();
112+
```
113+
114+
`10.0.0.10`这台机器,使用如下代码启动`TunnelClient`
115+
116+
```java
117+
ReverseTcpProxyTunnelClient.create(Vertx.vertx())
118+
.backendHost("10.0.0.10")
119+
.backendPort(22)
120+
.dataProxyName("ssh-proxy")
121+
.dataProxyHost("192.168.0.200")
122+
.dataProxyPort(22)
123+
.connect("192.168.0.200", 44444);
78124
```
79125

80126

81127

82-
## HTTP反向代理
128+
## 三、HTTP反向代理
83129

84130
实现HTTP反向代理,代理路由优先级如下
85131

src/main/java/top/meethigher/proxy/tcp/tunnel/ReverseTcpProxyTunnelClient.java

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@
1717
import java.util.concurrent.atomic.AtomicBoolean;
1818

1919
/**
20-
* 一个{@code ReverseTcpProxyTunnelClient} 对应一个失败重连的 TCP 连接。如果需要多个 TCP 连接,那么就需要创建多个 {@code ReverseTcpProxyTunnelClient} 实例
20+
* 一个{@code ReverseTcpProxyTunnelClient}内部维护不同的连接,分别为
21+
* <ul>
22+
* <li>一个控制连接,与{@code TunnelServer}通信,支持失败重连</li>
23+
* <li>多个数据连接,与{@code DataProxyServer}通信</li>
24+
* <li>多个后端连接,与你实际要内网穿透出去的服务通信</li>
25+
* </ul>
26+
* 其中,数据连接与后端连接绑定双向生命周期、双向数据传输。
2127
*
2228
* <p>背景:</p><p>我近期买了个树莓派,但是又不想随身带着树莓派,因此希望可以公网访问。</p>
2329
* <p>
@@ -103,6 +109,24 @@ public ReverseTcpProxyTunnelClient dataProxyName(String dataProxyName) {
103109
return this;
104110
}
105111

112+
public static ReverseTcpProxyTunnelClient create(Vertx vertx, NetClient netClient, long minDelay, long maxDelay, long heartbeatDelay, String secret, String name) {
113+
return new ReverseTcpProxyTunnelClient(vertx, netClient, minDelay, maxDelay, heartbeatDelay, secret, name);
114+
}
115+
116+
public static ReverseTcpProxyTunnelClient create(Vertx vertx, NetClient netClient, String secret) {
117+
return new ReverseTcpProxyTunnelClient(vertx, netClient, MIN_DELAY_DEFAULT, MAX_DELAY_DEFAULT, HEARTBEAT_DELAY_DEFAULT, secret, generateName());
118+
}
119+
120+
121+
public static ReverseTcpProxyTunnelClient create(Vertx vertx, NetClient netClient) {
122+
return new ReverseTcpProxyTunnelClient(vertx, netClient, MIN_DELAY_DEFAULT, MAX_DELAY_DEFAULT, HEARTBEAT_DELAY_DEFAULT, SECRET_DEFAULT, generateName());
123+
}
124+
125+
public static ReverseTcpProxyTunnelClient create(Vertx vertx) {
126+
return new ReverseTcpProxyTunnelClient(vertx, vertx.createNetClient(), MIN_DELAY_DEFAULT, MAX_DELAY_DEFAULT, HEARTBEAT_DELAY_DEFAULT, SECRET_DEFAULT, generateName());
127+
}
128+
129+
106130
/**
107131
* 注册内网穿透的监听逻辑
108132
*/
@@ -216,22 +240,4 @@ protected boolean doHandle(Vertx vertx, NetSocket netSocket, TunnelMessageType t
216240
});
217241
}
218242

219-
public static ReverseTcpProxyTunnelClient create(Vertx vertx, NetClient netClient, long minDelay, long maxDelay, long heartbeatDelay, String secret, String name) {
220-
return new ReverseTcpProxyTunnelClient(vertx, netClient, minDelay, maxDelay, heartbeatDelay, secret, name);
221-
}
222-
223-
public static ReverseTcpProxyTunnelClient create(Vertx vertx, NetClient netClient, String secret) {
224-
return new ReverseTcpProxyTunnelClient(vertx, netClient, MIN_DELAY_DEFAULT, MAX_DELAY_DEFAULT, HEARTBEAT_DELAY_DEFAULT, secret, generateName());
225-
}
226-
227-
228-
public static ReverseTcpProxyTunnelClient create(Vertx vertx, NetClient netClient) {
229-
return new ReverseTcpProxyTunnelClient(vertx, netClient, MIN_DELAY_DEFAULT, MAX_DELAY_DEFAULT, HEARTBEAT_DELAY_DEFAULT, SECRET_DEFAULT, generateName());
230-
}
231-
232-
public static ReverseTcpProxyTunnelClient create(Vertx vertx) {
233-
return new ReverseTcpProxyTunnelClient(vertx, vertx.createNetClient(), MIN_DELAY_DEFAULT, MAX_DELAY_DEFAULT, HEARTBEAT_DELAY_DEFAULT, SECRET_DEFAULT, generateName());
234-
}
235-
236-
237243
}

0 commit comments

Comments
 (0)