feat(network): 增强网络地址端口处理功能

- 添加IPv4地址与字节数组相互转换功能
- 实现ByteBuffer与网络地址端口的读写操作
- 增加网络端点字节数组序列化支持
- 添加Netty框架ByteBuf转换工具类
- 更新项目版本号至4.2.6
- 修改依赖引入方式为compileOnly
- 移除未使用的SuperStream导入
- 添加UUID类ByteBuffer读写功能
- 创建新的测试主函数验证功能
This commit is contained in:
Armamem0t 2026-01-06 14:36:13 +08:00
parent a081744f14
commit 2bcd4b329c
Signed by: minglipro
GPG Key ID: 5F355A77B22AA93B
7 changed files with 322 additions and 20 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2025 mingliqiye
* Copyright 2026 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,7 +16,7 @@
* ProjectName mingli-utils
* ModuleName mingli-utils
* CurrentFile build.gradle.kts
* LastUpdate 2025-09-21 15:36:59
* LastUpdate 2026-01-06 14:05:20
* UpdateUser MingLiPro
*/
@ -69,14 +69,14 @@ dependencies {
implementation("org.slf4j:slf4j-api:2.0.17")
implementation("com.mingliqiye.utils.jna:WinKernel32Api:1.0.1")
// https://github.com/jeremyh/jBCrypt
implementation("org.mindrot:jbcrypt:0.4")
compileOnly("org.mindrot:jbcrypt:0.4")
compileOnly("org.springframework.boot:spring-boot-starter:2.7.14")
compileOnly("com.fasterxml.jackson.core:jackson-databind:2.19.2")
compileOnly("com.google.code.gson:gson:2.13.1")
compileOnly("org.mybatis:mybatis:3.5.19")
compileOnly("com.alibaba.fastjson2:fastjson2:2.0.58")
compileOnly("io.netty:netty-all:4.2.9.Final")
compileOnly("com.baomidou:mybatis-plus-core:3.0.1")
compileOnly("net.java.dev.jna:jna:5.17.0")

View File

@ -1,5 +1,5 @@
#
# Copyright 2025 mingliqiye
# Copyright 2026 mingliqiye
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -16,13 +16,13 @@
# ProjectName mingli-utils
# ModuleName mingli-utils
# CurrentFile gradle.properties
# LastUpdate 2025-09-21 21:55:23
# LastUpdate 2026-01-06 14:35:41
# UpdateUser MingLiPro
#
JDKVERSIONS=1.8
GROUPSID=com.mingliqiye.utils
ARTIFACTID=mingli-utils
VERSIONS=4.2.4
VERSIONS=4.2.6
signing.keyId=B22AA93B
signing.password=
signing.secretKeyRingFile=secret.gpg

View File

@ -0,0 +1,42 @@
/*
* Copyright 2026 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile Main.kt
* LastUpdate 2026-01-06 14:04:14
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils
import com.mingliqiye.utils.network.NetworkEndpoint
import com.mingliqiye.utils.uuid.UUID
import java.nio.ByteBuffer
fun main() {
val byteBuffer = ByteBuffer.allocate(320)
NetworkEndpoint
.of("0:65532")
.writeIpv4toByteBuffer(byteBuffer)
UUID.getMaxUUID().writeToByteBuffer(byteBuffer)
byteBuffer.flip()
println(NetworkEndpoint.ofIpv4(byteBuffer))
println(UUID.of(byteBuffer))
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2025 mingliqiye
* Copyright 2026 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,7 +16,7 @@
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile Main.kt
* LastUpdate 2025-09-20 13:22:11
* LastUpdate 2026-01-06 14:36:10
* UpdateUser MingLiPro
*/
@file:JvmName("Main")
@ -24,12 +24,7 @@
package com.mingliqiye.utils.main
import com.mingliqiye.utils.springboot.autoconfigure.AutoConfiguration
import com.mingliqiye.utils.stream.SuperStream
fun main() {
AutoConfiguration.printBanner()
val data = SuperStream.of(Array(0) { 1 })
println(data)
}

View File

@ -0,0 +1,90 @@
/*
* Copyright 2026 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile NettyUtils.kt
* LastUpdate 2026-01-06 14:33:44
* UpdateUser MingLiPro
*/
@file:JvmName("NettyUtils")
package com.mingliqiye.utils.netty
import io.netty.buffer.ByteBuf
import io.netty.buffer.Unpooled
import java.nio.ByteBuffer
/**
* 将ByteBuffer转换为Netty的ByteBuf对象
*
* 该函数使用Netty库的Unpooled工具类将标准的java.nio.ByteBuffer包装成Netty的ByteBuf
* 以便在Netty框架中使用
*
* @receiver ByteBuffer 需要转换的原始ByteBuffer对象
* @return ByteBuf 转换后的Netty ByteBuf对象该对象包装了原始的ByteBuffer
*/
fun ByteBuffer.toByteBuf(): ByteBuf {
return Unpooled.wrappedBuffer(this)
}
/**
* 将Netty的ByteBuf对象转换为ByteBuffer
*
* 该函数通过ByteBuf的nioBuffer()方法将Netty的ByteBuf转换为标准的java.nio.ByteBuffer
*
* @receiver ByteBuf 需要转换的原始ByteBuf对象
* @return ByteBuffer 转换后的java.nio.ByteBuffer对象
*/
fun ByteBuf.toByteBuffer(): ByteBuffer {
return this.nioBuffer()
}
/**
* 将Netty的ByteBuf对象转换为字节数组
*
* 该函数将ByteBuf中的可读字节读取到一个新的字节数组中
*
* @receiver ByteBuf 需要转换的原始ByteBuf对象
* @return ByteArray 转换后的字节数组包含ByteBuf中所有可读的字节数据
*/
fun ByteBuf.toByteArray(): ByteArray {
val array = ByteArray(this.readableBytes())
this.readBytes(array)
return array
}
/**
* 将字节数组转换为Netty的ByteBuf对象
*
* 该函数使用Netty库的Unpooled工具类将字节数组包装成Netty的ByteBuf
* 以便在Netty框架中使用
*
* @receiver ByteArray 需要转换的原始字节数组
* @return ByteBuf 转换后的Netty ByteBuf对象该对象包装了原始的字节数组
*/
fun ByteArray.toByteBuf(): ByteBuf {
return Unpooled.wrappedBuffer(this)
}
/**
* 将字节数组转换为ByteBuffer对象
*
* @return 转换后的ByteBuffer对象该ByteBuffer包装了原始字节数组
*/
fun ByteArray.toByteBuffer(): ByteBuffer {
return ByteBuffer.wrap(this)
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2025 mingliqiye
* Copyright 2026 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,16 +16,18 @@
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile AddressPort.kt
* LastUpdate 2025-09-15 22:01:27
* LastUpdate 2026-01-06 14:03:47
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.network
import com.mingliqiye.utils.string.join
import java.io.Serializable
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.UnknownHostException
import java.nio.ByteBuffer
import java.util.regex.Pattern
/**
@ -80,6 +82,20 @@ class NetworkAddress private constructor(domip: String) : Serializable {
return NetworkAddress(domip)
}
@JvmStatic
fun ofIpv4(byteBuffer: ByteBuffer): NetworkAddress {
val byteArray = ByteArray(4)
byteBuffer.get(byteArray)
return ofIpv4(byteArray)
}
@JvmStatic
fun ofIpv4(byteArray: ByteArray): NetworkAddress {
return of(".".join(byteArray.map {
(it.toInt() and 0xFF).toString()
}))
}
/**
* 静态工厂方法通过 InetAddress 创建 NetworkAddress 实例
*
@ -182,6 +198,31 @@ class NetworkAddress private constructor(domip: String) : Serializable {
}
}
/**
* 将IPv4地址转换为字节数组
*
* @return 返回表示IPv4地址的4字节数组
* @throws NetworkException 当当前地址不是IPv4地址时抛出异常
*/
fun toIpv4ByteArray(): ByteArray {
// 验证地址类型是否为IPv4
if (iPv != IPV4) {
throw NetworkException("该地址 不是IPv4地址")
}
// 将IP地址字符串按点分割转换为整数并进行位运算处理最后转为字节数组
return ip!!.split(".").map { it.toInt() and 0xFF }.map { it.toByte() }.toByteArray()
}
/**
* 将IPv4地址写入到指定的ByteBuffer中
*
* @param byteBuffer 要写入的ByteBuffer对象IPv4地址将以字节数组形式写入到该缓冲区
* @return 返回写入了IPv4地址的ByteBuffer对象便于链式调用
*/
fun writeIpv4ToByteBuffer(byteBuffer: ByteBuffer): ByteBuffer {
return byteBuffer.put(toIpv4ByteArray())
}
/**
* 将当前 NetworkAddress 转换为 InetAddress 对象
*
@ -215,7 +256,54 @@ class NetworkPort : Serializable {
this.port = port
}
fun toByteArray(): ByteArray {
val byteArray = ByteArray(2)
byteArray[0] = (port shr 8 and 0xFF).toByte()
byteArray[1] = (port and 0xFF).toByte()
return byteArray
}
fun writeToByteBuffer(byteBuffer: ByteBuffer): ByteBuffer {
return byteBuffer.put(toByteArray())
}
companion object {
/**
* 创建NetworkPort实例
* @param port 端口号
* @return NetworkPort实例
*/
@JvmStatic
fun of(port: Int): NetworkPort {
return NetworkPort(port)
}
/**
* 从字节数组创建NetworkPort实例
* @param byteArray 包含端口信息的字节数组长度至少为2
* @return NetworkPort实例
*/
@JvmStatic
fun of(byteArray: ByteArray): NetworkPort {
// 将字节数组的前两个字节转换为端口号
val port = ((byteArray[0].toInt() and 0xFF) shl 8) or (byteArray[1].toInt() and 0xFF)
return of(port)
}
/**
* 从ByteBuffer创建NetworkPort实例
* @param byteBuffer 包含端口信息的ByteBuffer
* @return NetworkPort实例
*/
@JvmStatic
fun of(byteBuffer: ByteBuffer): NetworkPort {
val byteArray = ByteArray(2)
byteBuffer.get(byteArray)
return of(byteArray)
}
@JvmStatic
fun testPort(port: Int) {
// 验证端口号范围是否在0-65535之间
if (port !in 0..65535) {
@ -282,6 +370,42 @@ class NetworkEndpoint private constructor(
return NetworkEndpoint(networkAddress, networkPort)
}
/**
* 从字节数组创建IPv4网络端点
*
* @param byteArray 包含IPv4地址和端口信息的字节数组前4个字节表示IP地址后2个字节表示端口号
* @return NetworkEndpoint对象封装了IPv4地址和端口信息
*/
@JvmStatic
fun ofIpv4(byteArray: ByteArray): NetworkEndpoint {
// 提取前4个字节作为IP地址
val address = ByteArray(4) {
byteArray[it]
}
// 提取后2个字节作为端口号
val portInt = ByteArray(2) {
byteArray[it + 4]
}
return NetworkEndpoint(NetworkAddress.ofIpv4(address), NetworkPort.of(portInt))
}
/**
* 从字节缓冲区创建IPv4网络端点实例
*
* 该方法从给定的ByteBuffer中读取数据构建一个包含IPv4地址和端口的网络端点对象
* 该方法按照协议顺序从缓冲区中读取IPv4地址数据和端口数据
*
* @param byteBuffer 包含IPv4地址和端口数据的字节缓冲区缓冲区中的数据应按照先地址后端口的顺序排列
* @return 返回一个NetworkEndpoint实例包含从缓冲区解析出的IPv4地址和端口信息
*/
@JvmStatic
fun ofIpv4(byteBuffer: ByteBuffer): NetworkEndpoint {
return NetworkEndpoint(
NetworkAddress.ofIpv4(byteBuffer),
NetworkPort.of(byteBuffer)
)
}
/**
* 根据"host:port"格式的字符串创建NetworkEndpoint实例
* 例如"127.0.0.1:8080"
@ -327,7 +451,7 @@ class NetworkEndpoint private constructor(
* @return 包含详细信息的字符串
*/
override fun toString(): String {
return "NetworkEndpoint(IP=${networkAddress.ip},Port=${networkPort.port},Endpoint=${toHostPortString()})"
return "NetworkEndpoint(IP=${networkAddress.ip},Port=${networkPort.port})"
}
/**
@ -347,4 +471,39 @@ class NetworkEndpoint private constructor(
fun port(): Int {
return networkPort.port
}
/**
* 将网络地址和端口转换为IPv4字节数组
*
* 该函数将当前对象的网络地址转换为IPv4字节数组并与端口字节数组合并
* 生成一个包含6个字节的数组其中前4个字节为IPv4地址后2个字节为端口号
*
* @return ByteArray 包含6个字节的数组前4个字节为IPv4地址后2个字节为端口号
*/
fun toIpv4ByteArray(): ByteArray {
val ipv4ByteArray = networkAddress.toIpv4ByteArray()
val portByteArray = networkPort.toByteArray()
// 构建包含IPv4地址和端口的6字节数组
val byteArray = ByteArray(6) {
if (it < 4) {
ipv4ByteArray[it]
} else {
portByteArray[it - 4]
}
}
return byteArray
}
/**
* 将IPv4地址和端口信息写入字节缓冲区
*
* 该函数依次将网络地址的IPv4表示和网络端口写入到指定的字节缓冲区中
*
* @param byteBuffer 要写入数据的目标字节缓冲区
*/
fun writeIpv4toByteBuffer(byteBuffer: ByteBuffer): ByteBuffer {
networkAddress.writeIpv4ToByteBuffer(byteBuffer)
networkPort.writeToByteBuffer(byteBuffer)
return byteBuffer
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2025 mingliqiye
* Copyright 2026 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,7 +16,7 @@
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile UUID.kt
* LastUpdate 2025-09-21 21:53:40
* LastUpdate 2026-01-06 12:55:04
* UpdateUser MingLiPro
*/
@ -234,6 +234,19 @@ class UUID : Serializable {
return UUID(msb, lsb)
}
/**
* 从ByteBuffer创建UUID对象
*
* @param byteBuffer 包含UUID字节数据的ByteBuffer对象必须包含至少16个字节的数据
* @return 从ByteBuffer中读取的16个字节创建的UUID对象
*/
@JvmStatic
fun of(byteBuffer: ByteBuffer): UUID {
val byte = ByteArray(16)
byteBuffer.get(byte)
return UUID(byte)
}
/**
* 根据 MySQL UUID 字节数组创建 UUID 实例
*
@ -296,7 +309,6 @@ class UUID : Serializable {
return UUID(this)
}
/**
* 从字符串解析 UUID 字节数组
*
@ -422,6 +434,10 @@ class UUID : Serializable {
return data
}
fun writeToByteBuffer(byteBuffer: ByteBuffer): ByteBuffer {
return byteBuffer.put(data)
}
/**
* 返回 UUID 的高位长整型部分
*