From 6056f6fa9009f784ba760f75484bdfc8d44a9a00 Mon Sep 17 00:00:00 2001 From: minglipro Date: Sat, 5 Jul 2025 23:32:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 5 + build.yaml | 27 ----- gradle.properties | 4 +- settings.gradle.kts | 2 +- src/main/java/com/mingliqiye/Main.java | 13 --- .../java/com/mingliqiye/tcp/proxy/Main.java | 32 ++++++ .../java/com/mingliqiye/tcp/proxy/Proxy.java | 32 ++++++ .../com/mingliqiye/tcp/proxy/ProxyClient.java | 108 ++++++++++++++++++ .../com/mingliqiye/tcp/proxy/ServerEvent.java | 94 +++++++++++++++ src/main/resources/log4j2.yaml | 29 +++++ 10 files changed, 303 insertions(+), 43 deletions(-) delete mode 100644 build.yaml delete mode 100644 src/main/java/com/mingliqiye/Main.java create mode 100644 src/main/java/com/mingliqiye/tcp/proxy/Main.java create mode 100644 src/main/java/com/mingliqiye/tcp/proxy/Proxy.java create mode 100644 src/main/java/com/mingliqiye/tcp/proxy/ProxyClient.java create mode 100644 src/main/java/com/mingliqiye/tcp/proxy/ServerEvent.java create mode 100644 src/main/resources/log4j2.yaml diff --git a/build.gradle.kts b/build.gradle.kts index f5de2c4..8ff303d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,6 +38,11 @@ dependencies { testRuntimeOnly("org.junit.platform:junit-platform-launcher") implementation("org.jetbrains:annotations:24.0.0") annotationProcessor("org.jetbrains:annotations:24.0.0") + implementation("com.mingliqiye:network-endpoint:1.0.2") + implementation("com.mingliqiye:string-utilts:1.0.4") + implementation("com.mingliqiye:socket-utilts:1.0.6") + implementation("org.apache.logging.log4j:log4j-core:2.12.4") + implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.19.1") } tasks.test { diff --git a/build.yaml b/build.yaml deleted file mode 100644 index 585f85b..0000000 --- a/build.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Gitea Actions Build -run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 -on: - push: - branches: - - master -jobs: - Build: - runs-on: ubuntu-dev - steps: - - name: Check out repository code - uses: https://git.mingliqiye.com/Actions/checkout@v4 - - - name: build-test - run: | - source gradle.properties - gradle - gradle build-jar - - - name: Releases - run: | - source gradle.properties - SHA=${{gitea.sha}} - curl -o- https://git.mingliqiye.com/Actions/com.mingliqiye.gitea.releases/raw/branch/master/install.sh | bash - FILENAME="${GROUPSID}-${VERSIONS}.jar" - java -jar com.mingliqiye.gitea.releases.jar -s "${{gitea.server_url}}" -o "${{gitea.repository_owner}}" -r ${{gitea.event.repository.name}} -t "${{gitea.token}}" -ti "Auto releases ${{gitea.sha}} ${VERSIONS}" -b "# Auto releases wtih ${{gitea.event.head_commit.message}} - [${{gitea.sha}}](${{gitea.event.head_commit.url}})" -tn "Auto-Releases-${VERSIONS}-${SHA:0:10}" -a "build/libs" - diff --git a/gradle.properties b/gradle.properties index 58d8b22..ec23255 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ GROUPSID=com.mingliqiye -ARTIFACTID=socket-utilts +ARTIFACTID=tcp-proxy VERSIONS=0.1 -MAINCLASS=com.mingliqiye.Main +MAINCLASS=com.mingliqiye.tcp.proxy.Main JDKVERSIONS=1.8 diff --git a/settings.gradle.kts b/settings.gradle.kts index 79dab80..799301b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1 +1 @@ -rootProject.name = "socket-utilts" +rootProject.name = "tcp-proxy" diff --git a/src/main/java/com/mingliqiye/Main.java b/src/main/java/com/mingliqiye/Main.java deleted file mode 100644 index 1f285d4..0000000 --- a/src/main/java/com/mingliqiye/Main.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.mingliqiye; - -public class Main { - /** - * @param args [] - */ - public static void main(String[] args) { - System.out.print("Hello and welcome!"); - for (int i = 1; i <= 5; i++) { - System.out.println("i = " + i); - } - } -} diff --git a/src/main/java/com/mingliqiye/tcp/proxy/Main.java b/src/main/java/com/mingliqiye/tcp/proxy/Main.java new file mode 100644 index 0000000..0b292f4 --- /dev/null +++ b/src/main/java/com/mingliqiye/tcp/proxy/Main.java @@ -0,0 +1,32 @@ +package com.mingliqiye.tcp.proxy; + +import com.mingliqiye.network.endpoint.NetworkEndpoint; +import com.mingliqiye.network.endpoint.NetworkException; +import java.lang.reflect.Array; +import java.util.Arrays; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class Main { + + private static final Logger log = LogManager.getLogger(Main.class); + + public static void main(String[] args) { + log.info("启动中..."); + log.info("命令行输入 {}", Arrays.toString(args)); + if (args.length != 2) { + NetworkException exception = new NetworkException( + "请输入正确的地址代理地址" + ); + log.error(exception.getMessage(), exception); + log.warn("格式 *** 0:23335 127.0.0.1:25566"); + log.warn("格式 *** 本地打开 代理到远端"); + throw exception; + } + Proxy proxy = new Proxy( + NetworkEndpoint.of(args[0]), + NetworkEndpoint.of(args[1]) + ); + proxy.start(); + } +} diff --git a/src/main/java/com/mingliqiye/tcp/proxy/Proxy.java b/src/main/java/com/mingliqiye/tcp/proxy/Proxy.java new file mode 100644 index 0000000..4a181e0 --- /dev/null +++ b/src/main/java/com/mingliqiye/tcp/proxy/Proxy.java @@ -0,0 +1,32 @@ +package com.mingliqiye.tcp.proxy; + +import com.mingliqiye.network.endpoint.NetworkEndpoint; +import com.mingliqiye.utils.TcpSocketServer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class Proxy { + + private static Logger log = LogManager.getLogger(Proxy.class); + private final TcpSocketServer tcpSocketServer; + + Proxy(NetworkEndpoint endpoint, NetworkEndpoint remoteEndpoint) { + tcpSocketServer = new TcpSocketServer( + new ServerEvent(endpoint, remoteEndpoint) + ); + tcpSocketServer.bing(endpoint); + log.info( + "从 {} 代理到 {} 正在启动", + endpoint.toHostPortString(), + remoteEndpoint.toHostPortString() + ); + } + + public void start() { + tcpSocketServer.start(); + } + + public void close() { + tcpSocketServer.close(); + } +} diff --git a/src/main/java/com/mingliqiye/tcp/proxy/ProxyClient.java b/src/main/java/com/mingliqiye/tcp/proxy/ProxyClient.java new file mode 100644 index 0000000..b99281e --- /dev/null +++ b/src/main/java/com/mingliqiye/tcp/proxy/ProxyClient.java @@ -0,0 +1,108 @@ +package com.mingliqiye.tcp.proxy; + +import com.mingliqiye.network.endpoint.NetworkEndpoint; +import com.mingliqiye.utils.BufferBytesEntity; +import com.mingliqiye.utils.TcpSocketClient; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class ProxyClient extends Thread implements Closeable { + + private static Logger log = LogManager.getLogger(ProxyClient.class); + + private final String id; + + private final Socket socket = new Socket(); + private OutputStream outputStream; + private InputStream inputStream; + private final ServerEvent serverEvent; + private final TcpSocketClient client; + + public ProxyClient( + String id, + TcpSocketClient client, + ServerEvent serverEvent + ) { + this.id = id; + this.client = client; + this.serverEvent = serverEvent; + } + + public String getIds() { + return id; + } + + public boolean send(String id, BufferBytesEntity bufferBytesEntity) { + try { + this.outputStream.write( + bufferBytesEntity.getBytes(), + 0, + bufferBytesEntity.getLen() + ); + log.info( + "({})->({}) [{}bit]", + client.getEndpoint().toHostPortString(), + NetworkEndpoint.of( + (InetSocketAddress) socket.getRemoteSocketAddress() + ).toHostPortString(), + bufferBytesEntity.getLen() + ); + } catch (IOException e) { + return false; + } + return true; + } + + public boolean init(NetworkEndpoint endpoint) { + try { + socket.connect(endpoint.toInetSocketAddress()); + outputStream = socket.getOutputStream(); + inputStream = socket.getInputStream(); + } catch (IOException e) { + return false; + } + return true; + } + + public void run() { + byte[] bytes = new byte[1024]; + int readlen; + while (!Thread.currentThread().isInterrupted()) { + try { + readlen = this.inputStream.read(bytes); + if (readlen == -1) break; + client.send(bytes, 0, readlen); + log.info( + "({})->({}) [{}bit]", + NetworkEndpoint.of( + (InetSocketAddress) socket.getRemoteSocketAddress() + ).toHostPortString(), + client.getEndpoint().toHostPortString(), + readlen + ); + } catch (IOException e) { + break; + } + } + client.getFather().closeItem(client.getIds()); + } + + @Override + public void close() { + try { + socket.close(); + } catch (IOException ignored) {} + try { + outputStream.close(); + } catch (IOException ignored) {} + try { + inputStream.close(); + } catch (IOException ignored) {} + } +} diff --git a/src/main/java/com/mingliqiye/tcp/proxy/ServerEvent.java b/src/main/java/com/mingliqiye/tcp/proxy/ServerEvent.java new file mode 100644 index 0000000..0350e73 --- /dev/null +++ b/src/main/java/com/mingliqiye/tcp/proxy/ServerEvent.java @@ -0,0 +1,94 @@ +package com.mingliqiye.tcp.proxy; + +import com.mingliqiye.network.endpoint.NetworkEndpoint; +import com.mingliqiye.utils.BufferBytesEntity; +import com.mingliqiye.utils.TcpServerImplementation; +import com.mingliqiye.utils.TcpSocketClient; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class ServerEvent extends TcpServerImplementation { + + private final NetworkEndpoint endpoint; + private final NetworkEndpoint remoteEndpoint; + /** + * 客户端字典(线程安全的) + */ + private final Map clientMap = + new ConcurrentHashMap<>(); + private static Logger log = LogManager.getLogger(Proxy.class); + + public ServerEvent( + NetworkEndpoint endpoint, + NetworkEndpoint remoteEndpoint + ) { + this.endpoint = endpoint; + this.remoteEndpoint = remoteEndpoint; + } + + public boolean connect(TcpSocketClient client, String id) { + ProxyClient proxyClient = new ProxyClient(id, client, this); + if (!proxyClient.init(remoteEndpoint)) { + log.error( + "远端 {} 连接失败 已使客户端 {} 断开连接 当前连接数 {}", + remoteEndpoint.toHostPortString(), + client.getEndpoint().toHostPortString(), + clientMap.size() + ); + client.getFather().closeItem(id); + return false; + } + proxyClient.start(); + clientMap.put(id, proxyClient); + log.info( + "客户端 {} 连接成功 当前连接数 {}", + client.getEndpoint().toHostPortString(), + clientMap.size() + ); + return true; + } + + public void disconnect(TcpSocketClient client, String id) { + ProxyClient proxyClient = clientMap.get(client.getIds()); + if (proxyClient == null) { + return; + } + proxyClient.close(); + clientMap.remove(client.getIds()); + log.info( + "客户端 {} 断开连接 当前连接数 {}", + client.getEndpoint().toHostPortString(), + clientMap.size() + ); + } + + public void reception( + TcpSocketClient client, + BufferBytesEntity bufferBytesEntity + ) { + ProxyClient proxyClient = clientMap.get(client.getIds()); + if (proxyClient == null) { + return; + } + if (!proxyClient.send(client.getIds(), bufferBytesEntity)) { + client.getFather().closeItem(client.getIds()); + } + } + + public void started(ServerSocket serverSocket) { + log.info( + "服务器启动 监听 {}", + NetworkEndpoint.of( + (InetSocketAddress) serverSocket.getLocalSocketAddress() + ).toHostPortString() + ); + } + + public void closed() { + log.info("服务器已经关闭"); + } +} diff --git a/src/main/resources/log4j2.yaml b/src/main/resources/log4j2.yaml new file mode 100644 index 0000000..73a5906 --- /dev/null +++ b/src/main/resources/log4j2.yaml @@ -0,0 +1,29 @@ + +Appenders: + Console: #输出到控制台 + name: CONSOLE #Appender命名 + target: SYSTEM_OUT + PatternLayout: + pattern: "%style{%d{yyyy-MM-dd HH:mm:ss,SSS}}{bright,magenta} [%highlight{%p}{FATAL=white, ERROR=red, WARN=yellow, INFO=green, DEBUG=cyan, TRACE=blue}] [%style{%t}{bright,yellow}/%style{%c{1}}{bright,cyan}] -- %style{%m}{#EEDFCC}%n" #输出日志的格式 + disableAnsi: "${env:DISABLECOLOR:-false}" + RollingFile: + - name: FILE + fileName: 'log/info.log' + filePattern: "log/$${date:yyyy-MM-dd}/%d{yyyy-MM-dd}-%i.log" + PatternLayout: + pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS} [%p] [%t/%F:%L/%M/%c] -- %m%n" #输出日志的格式 + Policies: + SizeBasedTriggeringPolicy: + size: "10 KB" + TimeBasedTriggeringPolicy: + modulate: true + interval: 1 + DefaultRolloverStrategy: # 单目录下,文件最多20个,超过会删除最早之前的 + max: 1000 +Loggers: + Root: + level: INFO + additivity: true + AppenderRef: + - ref: CONSOLE + - ref: FILE