Files
KLALB/src/org/kne/cloud/network/IPv6SocketAddress.java
T

326 lines
9.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}