diff --git a/build.gradle.kts b/build.gradle.kts
index f5de2c4..b73e939 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -38,6 +38,8 @@ 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")
}
tasks.test {
diff --git a/src/main/java/com/mingliqiye/utils/BufferBytesEntity.java b/src/main/java/com/mingliqiye/utils/BufferBytesEntity.java
new file mode 100644
index 0000000..fc0b07b
--- /dev/null
+++ b/src/main/java/com/mingliqiye/utils/BufferBytesEntity.java
@@ -0,0 +1,35 @@
+package com.mingliqiye.utils;
+
+public class BufferBytesEntity {
+
+ /**
+ * 数据
+ */
+ private final byte[] bytes;
+ /**
+ * 数据大小
+ */
+ private final int len;
+ /**
+ * 缓存区大小
+ */
+ private final int buffer;
+
+ public BufferBytesEntity(byte[] bytes, int len, int buffer) {
+ this.bytes = bytes;
+ this.len = len;
+ this.buffer = buffer;
+ }
+
+ public byte[] getBytes() {
+ return bytes;
+ }
+
+ public int getLen() {
+ return len;
+ }
+
+ public int getBuffer() {
+ return buffer;
+ }
+}
diff --git a/src/main/java/com/mingliqiye/utils/DefTcpServerImplementation.java b/src/main/java/com/mingliqiye/utils/DefTcpServerImplementation.java
new file mode 100644
index 0000000..047d03c
--- /dev/null
+++ b/src/main/java/com/mingliqiye/utils/DefTcpServerImplementation.java
@@ -0,0 +1,63 @@
+package com.mingliqiye.utils;
+
+import com.mingliqiye.network.endpoint.NetworkEndpoint;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+
+public class DefTcpServerImplementation extends TcpServerImplementation {
+
+ boolean connect(TcpSocketClient client, String id) {
+ System.out.println(
+ StringUtil.format(
+ "客户端 {} ID={} 连接成功",
+ client.getEndpoint().toHostPortString(),
+ id
+ )
+ );
+ return true;
+ }
+
+ void disconnect(TcpSocketClient client, String id) {
+ System.out.println(
+ StringUtil.format(
+ "客户端 {} ID={} 断开连接",
+ client.getEndpoint().toHostPortString(),
+ id
+ )
+ );
+ }
+
+ void reception(
+ TcpSocketClient client,
+ BufferBytesEntity bufferBytesEntity
+ ) {
+ System.out.println(
+ StringUtil.format(
+ "来自客户端 {} ID:{} 的数据 大小:{}",
+ client.getEndpoint().toHostPortString(),
+ client.getIds(),
+ bufferBytesEntity.getLen()
+ )
+ );
+ client.send(
+ bufferBytesEntity.getBytes(),
+ 0,
+ bufferBytesEntity.getLen()
+ );
+ }
+
+ void started(ServerSocket serverSocket) {
+ System.out.println(
+ StringUtil.format(
+ "服务器启动 监听 {}",
+ NetworkEndpoint.of(
+ (InetSocketAddress) serverSocket.getLocalSocketAddress()
+ ).toHostPortString()
+ )
+ );
+ }
+
+ void closed() {
+ System.out.println("服务器已经关闭");
+ }
+}
diff --git a/src/main/java/com/mingliqiye/utils/Main.java b/src/main/java/com/mingliqiye/utils/Main.java
new file mode 100644
index 0000000..2bae5a4
--- /dev/null
+++ b/src/main/java/com/mingliqiye/utils/Main.java
@@ -0,0 +1,12 @@
+package com.mingliqiye.utils;
+
+import com.mingliqiye.network.endpoint.NetworkEndpoint;
+
+public class Main {
+
+ public static void main(String[] args) {
+ TcpSocketServer tcpSocketServer = new TcpSocketServer(null);
+ tcpSocketServer.bing(NetworkEndpoint.of("127.0.0.1:3621"));
+ tcpSocketServer.start();
+ }
+}
diff --git a/src/main/java/com/mingliqiye/utils/TcpServerImplementation.java b/src/main/java/com/mingliqiye/utils/TcpServerImplementation.java
new file mode 100644
index 0000000..6929881
--- /dev/null
+++ b/src/main/java/com/mingliqiye/utils/TcpServerImplementation.java
@@ -0,0 +1,34 @@
+package com.mingliqiye.utils;
+
+import java.net.ServerSocket;
+
+/**
+ * 回调函数们
+ * @see DefTcpServerImplementation 示例
+ */
+public abstract class TcpServerImplementation {
+
+ /**
+ * 连接回调函数
+ * @param client 客户端
+ * @param id 客户端ID
+ * @return 是否允许连接
+ */
+ abstract boolean connect(TcpSocketClient client, String id);
+
+ /**
+ * 断开连接回调函数
+ * @param client 客户端
+ * @param id 客户端ID
+ */
+ abstract void disconnect(TcpSocketClient client, String id);
+
+ abstract void reception(
+ TcpSocketClient client,
+ BufferBytesEntity bufferBytesEntity
+ );
+
+ abstract void started(ServerSocket serverSocket);
+
+ abstract void closed();
+}
diff --git a/src/main/java/com/mingliqiye/utils/TcpSocketClient.java b/src/main/java/com/mingliqiye/utils/TcpSocketClient.java
new file mode 100644
index 0000000..be4fe44
--- /dev/null
+++ b/src/main/java/com/mingliqiye/utils/TcpSocketClient.java
@@ -0,0 +1,127 @@
+package com.mingliqiye.utils;
+
+import com.mingliqiye.network.endpoint.NetworkEndpoint;
+import com.mingliqiye.network.endpoint.NetworkException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+public class TcpSocketClient extends Thread {
+
+ private final InputStream inputStream;
+ private final OutputStream outputStream;
+ private final Socket socket;
+ private final TcpServerImplementation tcpServerImplementation;
+ private final TcpSocketServer father;
+ private final String id;
+ private final NetworkEndpoint endpoint;
+ private boolean closed = false;
+
+ public String getIds() {
+ return id;
+ }
+
+ public TcpSocketClient(
+ InputStream inputStream,
+ OutputStream outputStream,
+ Socket socket,
+ TcpServerImplementation tcpServerImplementation,
+ TcpSocketServer father,
+ String id
+ ) {
+ this.inputStream = inputStream;
+ this.outputStream = outputStream;
+ this.socket = socket;
+ this.tcpServerImplementation = tcpServerImplementation;
+ this.father = father;
+ this.id = id;
+ this.endpoint = NetworkEndpoint.of(
+ (InetSocketAddress) socket.getRemoteSocketAddress()
+ );
+ }
+
+ public void run() {
+ while (!Thread.currentThread().isInterrupted()) {
+ try {
+ BufferBytesEntity bufferBytesEntity = recv(1024);
+ if (bufferBytesEntity.getLen() == -1) break;
+ tcpServerImplementation.reception(this, bufferBytesEntity);
+ } catch (NetworkException e) {
+ break;
+ }
+ }
+ father.closeItem(id);
+ }
+
+ /**
+ * 发送指定字节长度
+ * @param bytes 字节
+ * @param off 位移
+ * @param len 长度
+ */
+ public void send(byte[] bytes, int off, int len) {
+ try {
+ outputStream.write(bytes, off, len);
+ } catch (IOException e) {
+ throw new NetworkException(e);
+ }
+ }
+
+ /**
+ * 发送字节
+ * 注意 byte数组有多大发多大数组内空着的发送 0X00
+ * @param bytes 字节
+ */
+ public void send(byte[] bytes) {
+ send(bytes, 0, bytes.length);
+ }
+
+ /**
+ * 读取指定大小buffer的数据
+ *
+ * @param buffer 缓存区大小
+ * @return BufferBytesEntity
+ * @see BufferBytesEntity
+ */
+ public BufferBytesEntity recv(int buffer) {
+ byte[] bytes = new byte[buffer];
+ try {
+ return new BufferBytesEntity(
+ bytes,
+ inputStream.read(bytes),
+ buffer
+ );
+ } catch (IOException e) {
+ throw new NetworkException(e);
+ }
+ }
+
+ public void close() {
+ if (closed) {
+ return;
+ }
+ closed = true;
+ tcpServerImplementation.disconnect(this, id);
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ throw new NetworkException(e);
+ }
+ try {
+ outputStream.close();
+ } catch (IOException e) {
+ throw new NetworkException(e);
+ }
+ try {
+ socket.close();
+ } catch (IOException e) {
+ throw new NetworkException(e);
+ }
+ }
+
+ public NetworkEndpoint getEndpoint() {
+ return endpoint;
+ }
+}
diff --git a/src/main/java/com/mingliqiye/utils/TcpSocketServer.java b/src/main/java/com/mingliqiye/utils/TcpSocketServer.java
new file mode 100644
index 0000000..d25308e
--- /dev/null
+++ b/src/main/java/com/mingliqiye/utils/TcpSocketServer.java
@@ -0,0 +1,100 @@
+package com.mingliqiye.utils;
+
+import com.mingliqiye.network.endpoint.NetworkEndpoint;
+import com.mingliqiye.network.endpoint.NetworkException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * tcp 服务器 类
+ */
+public class TcpSocketServer extends Thread implements AutoCloseable {
+
+ /**
+ * 客户端字典(线程安全的)
+ */
+ private final Map clientMap =
+ new ConcurrentHashMap<>();
+
+ private ServerSocket serverSocket;
+
+ private final TcpServerImplementation tcpServerImplementation;
+
+ public TcpSocketServer(TcpServerImplementation tcpServerImplementation) {
+ if (tcpServerImplementation == null) {
+ tcpServerImplementation = new DefTcpServerImplementation();
+ }
+ this.tcpServerImplementation = tcpServerImplementation;
+ }
+
+ /**
+ * 绑定地址和端口号
+ *
+ * @param endpoint 地址和端口号
+ * @throws NetworkException 网络错误
+ */
+ public void bing(NetworkEndpoint endpoint) {
+ try {
+ serverSocket = new ServerSocket();
+ serverSocket.bind(endpoint.toInetSocketAddress());
+ } catch (IOException e) {
+ throw new NetworkException(e);
+ }
+ }
+
+ public void run() {
+ tcpServerImplementation.started(serverSocket);
+ while (!Thread.currentThread().isInterrupted()) {
+ try {
+ String uuid = UUID.randomUUID().toString();
+ Socket socket = serverSocket.accept();
+ TcpSocketClient tcpSocketClient = new TcpSocketClient(
+ socket.getInputStream(),
+ socket.getOutputStream(),
+ socket,
+ tcpServerImplementation,
+ this,
+ uuid
+ );
+ if (!tcpServerImplementation.connect(tcpSocketClient, uuid)) {
+ tcpSocketClient.close();
+ return;
+ }
+ clientMap.put(uuid, tcpSocketClient);
+ tcpSocketClient.start();
+ } catch (InterruptedIOException e) {
+ Thread.currentThread().interrupt();
+ break;
+ } catch (IOException e) {
+ throw new NetworkException(e);
+ }
+ }
+ }
+
+ public void closeItem(String id) {
+ TcpSocketClient tcpSocketClient = clientMap.get(id);
+ if (tcpSocketClient == null) {
+ return;
+ }
+ clientMap.remove(id);
+ tcpSocketClient.close();
+ }
+
+ @Override
+ public void close() {
+ tcpServerImplementation.closed();
+ clientMap.forEach((k, v) -> {
+ v.close();
+ });
+ clientMap.clear();
+ this.interrupt();
+ try {
+ serverSocket.close();
+ } catch (IOException e) {}
+ }
+}
diff --git a/workflows/build.yaml b/workflows/build.yaml
deleted file mode 100644
index 585f85b..0000000
--- a/workflows/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"
-