package org.kne.cloud.network; import java.net.Inet6Address; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; import org.kne.cloud.network.ipv6.IPv6Address; /** * 高性能IPv6套接字地址实现,替代Java原生的InetSocketAddress * 大幅减少GC压力和提高网络栈性能 */ public final class IPv6SocketAddress { private static final long serialVersionUID = 1L; private final IPv6Address address; private final int port; // 常用常量 public static final IPv6SocketAddress ANY = new IPv6SocketAddress(IPv6Address.UNSPECIFIED, 0); // 构造方法 public IPv6SocketAddress(IPv6Address address, int port ) { if (address == null) { throw new IllegalArgumentException("Address cannot be null"); } if (port < 0 || port > 65535) { throw new IllegalArgumentException("Port out of range: " + port); } this.address = address; this.port = port; } /** * 从IPv6地址和端口创建 */ public static IPv6SocketAddress valueOf(IPv6Address address, int port) { return new IPv6SocketAddress(address, port); } /** * 从两个long和端口创建(最高性能) */ public static IPv6SocketAddress valueOf(long high, long low, int port) { return new IPv6SocketAddress(IPv6Address.valueOf(high, low), port); } /** * 从byte[16]和端口创建 */ public static IPv6SocketAddress valueOf(byte[] addressBytes, int port) { return new IPv6SocketAddress(IPv6Address.valueOf(addressBytes), port); } /** * 从ByteBuffer创建(零拷贝友好) */ public static IPv6SocketAddress valueOf(ByteBuffer buffer) { if (buffer.remaining() < 18) { // 16字节地址 + 2字节端口 throw new IllegalArgumentException("Buffer must have at least 18 bytes remaining"); } long high = buffer.getLong(); long low = buffer.getLong(); int port = buffer.getShort() & 0xFFFF; return valueOf(high, low, port); } /** * 从ByteBuffer指定位置创建 */ public static IPv6SocketAddress valueOf(int offset, ByteBuffer buffer) { if (buffer.remaining() < offset + 18) { throw new IllegalArgumentException("Buffer too small"); } long high = buffer.getLong(offset); long low = buffer.getLong(offset + 8); int port = buffer.getShort(offset + 16) & 0xFFFF; return valueOf(high, low, port); } /** * 从Java InetSocketAddress转换 */ public static IPv6SocketAddress valueOf(InetSocketAddress inetSocketAddress) { if (inetSocketAddress == null) { throw new IllegalArgumentException("InetSocketAddress cannot be null"); } IPv6Address addr = IPv6Address.valueOf(inetSocketAddress.getAddress()); int port = inetSocketAddress.getPort(); return new IPv6SocketAddress(addr, port); } /** * 从字符串解析(格式: [ipv6]:port 或 ipv6:port) */ public static IPv6SocketAddress valueOf(String socketAddress) { if (socketAddress == null || socketAddress.isEmpty()) { throw new IllegalArgumentException("Invalid socket address string"); } try { // 处理[ipv6]:port格式 if (socketAddress.startsWith("[")) { int closeBracket = socketAddress.indexOf(']'); if (closeBracket == -1) { throw new IllegalArgumentException("Invalid IPv6 socket address format"); } String ipPart = socketAddress.substring(1, closeBracket); String portPart = socketAddress.substring(closeBracket + 1); if (!portPart.startsWith(":")) { throw new IllegalArgumentException("Invalid IPv6 socket address format"); } IPv6Address address = IPv6Address.valueOf(ipPart); int port = Integer.parseInt(portPart.substring(1)); return valueOf(address, port); } else { // 处理ipv6:port格式(简单情况) int lastColon = socketAddress.lastIndexOf(':'); if (lastColon == -1) { throw new IllegalArgumentException("Invalid IPv6 socket address format"); } String ipPart = socketAddress.substring(0, lastColon); String portPart = socketAddress.substring(lastColon + 1); IPv6Address address = IPv6Address.valueOf(ipPart); int port = Integer.parseInt(portPart); return valueOf(address, port); } } catch (Exception e) { throw new IllegalArgumentException("Invalid IPv6 socket address: " + socketAddress, e); } } /** * 创建未解析的地址(带hostname) * @throws UnknownHostException */ public static IPv6SocketAddress createUnresolved(String hostname, int port) throws UnknownHostException { if (hostname == null || hostname.isEmpty()) { throw new IllegalArgumentException("Hostname cannot be null or empty"); } if (port < 0 || port > 65535) { throw new IllegalArgumentException("Port out of range: " + port); } return new IPv6SocketAddress(IPv6Address.valueOf ( hostname), port); } // 核心getter方法 public IPv6Address getAddress() { return address; } public int getPort() { return port; } /** * 转换为byte数组(18字节:16字节地址 + 2字节端口) */ public byte[] toByteArray() { byte[] bytes = new byte[18]; toByteArray(bytes, 0); return bytes; } /** * 写入到现有byte数组 */ public void toByteArray(byte[] dest, int offset) { if (dest.length - offset < 18) { throw new IllegalArgumentException("Destination array too small"); } address.toByteArray(dest, offset); dest[offset + 16] = (byte) (port >> 8); dest[offset + 17] = (byte) port; } /** * 写入到ByteBuffer(高性能网络操作) */ public void writeTo(ByteBuffer buffer) { address.writeTo(buffer); buffer.putShort((short) port); } /** * 写入到ByteBuffer指定位置 */ public void writeTo(int offset, ByteBuffer buffer) { address.writeTo(offset, buffer); buffer.putShort(offset + 16, (short) port); } /** * 转换为Java InetSocketAddress(兼容性方法) */ public InetSocketAddress toInetSocketAddress() { Inet6Address inet6Addr = address.toInet6Address(); return new InetSocketAddress(inet6Addr, port); } // 实用方法 /** * 检查是否为通配符地址(0.0.0.0:0) */ public boolean isWildcardAddress() { return address.equals(IPv6Address.UNSPECIFIED) && port == 0; } /** * 检查是否为环回地址 */ public boolean isLoopbackAddress() { return address.isLoopbackAddress(); } /** * 检查是否为多播地址 */ public boolean isMulticastAddress() { return address.isMulticastAddress(); } /** * 检查是否为链路本地地址 */ public boolean isLinkLocalAddress() { return address.isLinkLocalAddress(); } /** * 检查是否为站点本地地址 */ public boolean isSiteLocalAddress() { return address.isSiteLocalAddress(); } /** * 获取多播地址的scope */ public int getMulticastScope() { return address.getMulticastScope(); } // 路由相关的实用方法 /** * 检查地址是否在指定网络内 */ public boolean isInNetwork(IPv6Address network, int prefixLength) { return address.isInNetwork(network, prefixLength); } /** * 应用网络掩码 */ public IPv6SocketAddress maskWith(IPv6Address mask) { return valueOf(address.maskWith(mask), port); } // 比较和哈希 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((address == null) ? 0 : address.hashCode()); result = prime * result + port; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; IPv6SocketAddress other = (IPv6SocketAddress) obj; if (address == null) { if (other.address != null) return false; } else if (!address.equals(other.address)) return false; if (port != other.port) return false; return true; } @Override public String toString() { // 对于IPv6地址,使用方括号括起来 return "[" + address.toString() + "]:" + port; } /** * 转换为压缩形式的字符串 */ public String toCompressedString() { return "[" + address.toCompressedString() + "]:" + port; } }