下面列出了怎么用java.net.StandardProtocolFamily的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
/**
* Encodes the given InetSocketAddress into this socket address.
* @param protocolFamily protocol family
* @param isa the InetSocketAddress to encode
* @return the size of the socket address (sizeof sockaddr or sockaddr6)
* @throws UnsupportedAddressTypeException if the address type is not supported
*/
int encode(ProtocolFamily protocolFamily, InetSocketAddress isa) {
if (protocolFamily == StandardProtocolFamily.INET) {
// struct sockaddr
InetAddress ia = isa.getAddress();
if (!(ia instanceof Inet4Address))
throw new UnsupportedAddressTypeException();
putFamily(AF_INET);
putAddress(AF_INET, ia);
putPort(AF_INET, isa.getPort());
return SIZEOF_SOCKADDR4;
} else {
// struct sockaddr6
putFamily(AF_INET6);
putAddress(AF_INET6, isa.getAddress());
putPort(AF_INET6, isa.getPort());
UNSAFE.putInt(address + OFFSET_SIN6_FLOWINFO, 0);
return SIZEOF_SOCKADDR6;
}
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
public static InetAddress getDefaultRoute(Class<? extends InetAddress> type) {
InetAddress target = null;
ProtocolFamily family = type == Inet6Address.class ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
try(DatagramChannel chan=DatagramChannel.open(family)) {
if(type == Inet4Address.class)
target = InetAddress.getByAddress(new byte[] {8,8,8,8});
if(type == Inet6Address.class)
target = InetAddress.getByName("2001:4860:4860::8888");
chan.connect(new InetSocketAddress(target,63));
InetSocketAddress soa = (InetSocketAddress) chan.getLocalAddress();
InetAddress local = soa.getAddress();
if(type.isInstance(local) && !local.isAnyLocalAddress())
return local;
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@Override
public void start(Collection<DHT> dhts, ConfigReader config) {
try {
channel = DatagramChannel.open(StandardProtocolFamily.INET);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, 1);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
// we only need to send, not to receive, so need to bind to a specific port
channel.bind(new InetSocketAddress(0));
channel.connect(new InetSocketAddress(InetAddress.getByAddress(new byte[] {(byte) 224,0,23,5}), 9696));
} catch (IOException e) {
e.printStackTrace();
return;
}
t.setDaemon(true);
t.setName("opentracker-sync");
t.start();
// OT-sync only supports ipv4 atm
dhts.stream().filter(d -> d.getType().PREFERRED_ADDRESS_TYPE == Inet4Address.class).forEach(d -> {
d.addIncomingMessageListener(this::incomingPacket);
});
}
public LocalServiceDiscoveryInfo(
Set<SocketChannelConnectionAcceptor> socketAcceptors,
Collection<AnnounceGroup> announceGroups) {
this.localPorts = unmodifiableSet(collectLocalPorts(socketAcceptors));
Collection<NetworkInterface> networkInterfaces = new HashSet<>();
boolean acceptIP4 = false;
boolean acceptIP6 = false;
for (SocketChannelConnectionAcceptor acceptor : socketAcceptors) {
networkInterfaces.add(acceptor.getNetworkInterface());
InetSocketAddress address = acceptor.getLocalAddress();
ProtocolFamily protocolFamily = InternetProtocolUtils.getProtocolFamily(address.getAddress());
if (protocolFamily == StandardProtocolFamily.INET) {
acceptIP4 = true;
} else {
acceptIP6 = true;
}
if (acceptIP4 && acceptIP6) {
break; // no need to look further
}
}
this.compatibleGroups = unmodifiableCollection(collectCompatibleGroups(announceGroups, acceptIP4, acceptIP6));
this.networkInterfaces = unmodifiableCollection(networkInterfaces);
}
public DatagramBulkClient(String name,
InetSocketAddress bindAddress,
InetSocketAddress connectAddress,
long limit,
CyclicBarrier readBarrier,
CyclicBarrier sentBarrier) throws IOException
{
this.channel = DatagramChannel.open(StandardProtocolFamily.INET);
this.channel.configureBlocking(true);
this.channel.bind(bindAddress);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Bulk client {}: BIND<{}> CONNECT<{}>",
new Object[]{name, bindAddress, connectAddress});
}
this.consumer = new Consumer(channel, name, limit, connectAddress, readBarrier);
this.producer = new Producer(channel, name, limit, connectAddress, sentBarrier);
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
public static MarketData open(NetworkInterface multicastInterface,
InetSocketAddress multicastGroup, InetSocketAddress requestAddress,
long instrument) throws IOException {
DatagramChannel channel = DatagramChannel.open(StandardProtocolFamily.INET);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.bind(new InetSocketAddress(multicastGroup.getPort()));
channel.join(multicastGroup.getAddress(), multicastInterface);
channel.configureBlocking(false);
DatagramChannel requestChannel = DatagramChannel.open(StandardProtocolFamily.INET);
requestChannel.configureBlocking(false);
return new MarketData(channel, requestChannel, requestAddress, instrument);
}
public static InetAddress getDefaultRoute(Class<? extends InetAddress> type) {
InetAddress target = null;
ProtocolFamily family = type == Inet6Address.class ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
try(DatagramChannel chan=DatagramChannel.open(family)) {
if(type == Inet4Address.class)
target = InetAddress.getByAddress(new byte[] {8,8,8,8});
if(type == Inet6Address.class)
target = InetAddress.getByName("2001:4860:4860::8888");
chan.connect(new InetSocketAddress(target,63));
InetSocketAddress soa = (InetSocketAddress) chan.getLocalAddress();
InetAddress local = soa.getAddress();
if(type.isInstance(local) && !local.isAnyLocalAddress())
return local;
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@Override
public void start(Collection<DHT> dhts, ConfigReader config) {
try {
channel = DatagramChannel.open(StandardProtocolFamily.INET);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, 1);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
// we only need to send, not to receive, so need to bind to a specific port
channel.bind(new InetSocketAddress(0));
channel.connect(new InetSocketAddress(InetAddress.getByAddress(new byte[] {(byte) 224,0,23,5}), 9696));
} catch (IOException e) {
e.printStackTrace();
return;
}
t.setDaemon(true);
t.setName("opentracker-sync");
t.start();
// OT-sync only supports ipv4 atm
dhts.stream().filter(d -> d.getType().PREFERRED_ADDRESS_TYPE == Inet4Address.class).forEach(d -> {
d.addIncomingMessageListener(this::incomingPacket);
});
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
/**
* Returns a new host endpoint with the specified IP address.
*
* @return the new endpoint with the specified IP address.
* {@code this} if this endpoint has the same IP address.
*
* @throws IllegalStateException if this endpoint is not a host but a group
*/
public Endpoint withIpAddr(@Nullable String ipAddr) {
if (ipAddr == null) {
return withoutIpAddr();
}
if (NetUtil.isValidIpV4Address(ipAddr)) {
return withIpAddr(ipAddr, StandardProtocolFamily.INET);
}
if (NetUtil.isValidIpV6Address(ipAddr)) {
if (ipAddr.charAt(0) == '[') {
ipAddr = ipAddr.substring(1, ipAddr.length() - 1);
}
return withIpAddr(ipAddr, StandardProtocolFamily.INET6);
}
throw new IllegalArgumentException("ipAddr: " + ipAddr + " (expected: an IP address)");
}
private Endpoint withIpAddr(String ipAddr, StandardProtocolFamily ipFamily) {
if (ipAddr.equals(this.ipAddr)) {
return this;
}
// Replace the host name as well if the host name is an IP address.
if (isIpAddrOnly()) {
return new Endpoint(ipAddr, ipAddr, port, weight,
ipFamily == StandardProtocolFamily.INET ? HostType.IPv4_ONLY
: HostType.IPv6_ONLY);
}
return new Endpoint(host(), ipAddr, port, weight,
ipFamily == StandardProtocolFamily.INET ? HostType.HOSTNAME_AND_IPv4
: HostType.HOSTNAME_AND_IPv6);
}
@Test
void hostWithIpAddr() {
final Endpoint foo = Endpoint.of("foo.com").withIpAddr("192.168.0.1");
assertThat(foo.authority()).isEqualTo("foo.com");
assertThat(foo.ipAddr()).isEqualTo("192.168.0.1");
assertThat(foo.ipFamily()).isEqualTo(StandardProtocolFamily.INET);
assertThat(foo.hasIpAddr()).isTrue();
assertThat(foo.toUri("none+http").toString()).isEqualTo("none+http://foo.com");
assertThat(foo.withIpAddr(null).ipAddr()).isNull();
assertThat(foo.withIpAddr(null).toUri("none+http").toString()).isEqualTo("none+http://foo.com");
assertThat(foo.withIpAddr("::1").authority()).isEqualTo("foo.com");
assertThat(foo.withIpAddr("::1").ipAddr()).isEqualTo("::1");
assertThat(foo.withIpAddr("::1").ipFamily()).isEqualTo(StandardProtocolFamily.INET6);
assertThat(foo.withIpAddr("::1").hasIpAddr()).isTrue();
assertThat(foo.withIpAddr("::1").toUri("none+http").toString()).isEqualTo("none+http://foo.com");
assertThat(foo.withIpAddr("192.168.0.1")).isSameAs(foo);
assertThat(foo.withIpAddr("192.168.0.2").authority()).isEqualTo("foo.com");
assertThat(foo.withIpAddr("192.168.0.2").ipAddr()).isEqualTo("192.168.0.2");
assertThat(foo.withIpAddr("192.168.0.2").ipFamily()).isEqualTo(StandardProtocolFamily.INET);
assertThat(foo.withIpAddr("192.168.0.2").hasIpAddr()).isTrue();
assertThat(foo.withIpAddr("192.168.0.2").toUri("none+http").toString())
.isEqualTo("none+http://foo.com");
assertThatThrownBy(() -> foo.withIpAddr("no-ip")).isInstanceOf(IllegalArgumentException.class);
}
/**
* Create a new broadcaster
*
* @param address - multicast group address
* @param srcAddress - address of interface we should use to broadcast.
* @param port - udp port to use
* @param ttl - packet ttl
* @throws IOException
*/
public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
throws IOException, JdpException {
this.addr = address;
this.port = port;
ProtocolFamily family = (address instanceof Inet6Address)
? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
channel = DatagramChannel.open(family);
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// with srcAddress equal to null, this constructor do exactly the same as
// if srcAddress is not passed
if (srcAddress != null) {
// User requests particular interface to bind to
NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
try {
channel.bind(new InetSocketAddress(srcAddress, 0));
} catch (UnsupportedAddressTypeException ex) {
throw new JdpException("Unable to bind to source address");
}
channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
}
}
private static Map<RegistryKey,OptionKey> options() {
Map<RegistryKey,OptionKey> map =
new HashMap<RegistryKey,OptionKey>();
map.put(new RegistryKey(StandardSocketOptions.SO_BROADCAST, Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_BROADCAST));
map.put(new RegistryKey(StandardSocketOptions.SO_KEEPALIVE, Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_KEEPALIVE));
map.put(new RegistryKey(StandardSocketOptions.SO_LINGER, Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_LINGER));
map.put(new RegistryKey(StandardSocketOptions.SO_SNDBUF, Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_SNDBUF));
map.put(new RegistryKey(StandardSocketOptions.SO_RCVBUF, Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_RCVBUF));
map.put(new RegistryKey(StandardSocketOptions.SO_REUSEADDR, Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_REUSEADDR));
map.put(new RegistryKey(StandardSocketOptions.TCP_NODELAY, Net.UNSPEC), new OptionKey(6, TCP_NODELAY));
map.put(new RegistryKey(StandardSocketOptions.IP_TOS, StandardProtocolFamily.INET), new OptionKey(0, IP_TOS));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_IF, StandardProtocolFamily.INET), new OptionKey(0, IP_MULTICAST_IF));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_TTL, StandardProtocolFamily.INET), new OptionKey(0, IP_MULTICAST_TTL));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_LOOP, StandardProtocolFamily.INET), new OptionKey(0, IP_MULTICAST_LOOP));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_IF, StandardProtocolFamily.INET6), new OptionKey(41, IPV6_MULTICAST_IF));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_TTL, StandardProtocolFamily.INET6), new OptionKey(41, IPV6_MULTICAST_HOPS));
map.put(new RegistryKey(StandardSocketOptions.IP_MULTICAST_LOOP, StandardProtocolFamily.INET6), new OptionKey(41, IPV6_MULTICAST_LOOP));
map.put(new RegistryKey(ExtendedSocketOption.SO_OOBINLINE, Net.UNSPEC), new OptionKey(SOL_SOCKET, SO_OOBINLINE));
return map;
}
/**
* Convert the {@link InternetProtocolFamily}. This MUST only be called on jdk version >= 7.
*/
public static ProtocolFamily convert(InternetProtocolFamily family) {
switch (family) {
case IPv4:
return StandardProtocolFamily.INET;
case IPv6:
return StandardProtocolFamily.INET6;
default:
throw new IllegalArgumentException();
}
}
/** Create UDP channel
*
* @param broadcast Support broadcast?
* @param port Port to use or 0 to auto-assign
* @return UDP channel
* @throws Exception on error
*/
public static DatagramChannel createUDP(boolean broadcast, int port) throws Exception
{
// Current use of multicast addresses works only with INET, not INET6
final DatagramChannel udp = DatagramChannel.open(StandardProtocolFamily.INET);
udp.configureBlocking(true);
if (broadcast)
udp.socket().setBroadcast(true);
udp.socket().setReuseAddress(true);
udp.bind(new InetSocketAddress(port));
return udp;
}
static InetSocketAddress checkAddress(SocketAddress sa, ProtocolFamily family) {
InetSocketAddress isa = checkAddress(sa);
if (family == StandardProtocolFamily.INET) {
InetAddress addr = isa.getAddress();
if (!(addr instanceof Inet4Address))
throw new UnsupportedAddressTypeException();
}
return isa;
}
static void bind(ProtocolFamily family, FileDescriptor fd,
InetAddress addr, int port) throws IOException
{
boolean preferIPv6 = isIPv6Available() &&
(family != StandardProtocolFamily.INET);
if (addr.isLinkLocalAddress()) {
addr = IPAddressUtil.toScopedAddress(addr);
}
bind0(fd, preferIPv6, exclusiveBind, addr, port);
}
static int connect(ProtocolFamily family, FileDescriptor fd, InetAddress remote, int remotePort)
throws IOException
{
if (remote.isLinkLocalAddress()) {
remote = IPAddressUtil.toScopedAddress(remote);
}
boolean preferIPv6 = isIPv6Available() &&
(family != StandardProtocolFamily.INET);
return connect0(preferIPv6, fd, remote, remotePort);
}
@Override
public <T> SocketChannel setOption(SocketOption<T> name, T value)
throws IOException
{
Objects.requireNonNull(name);
if (!supportedOptions().contains(name))
throw new UnsupportedOperationException("'" + name + "' not supported");
if (!name.type().isInstance(value))
throw new IllegalArgumentException("Invalid value '" + value + "'");
synchronized (stateLock) {
ensureOpen();
if (name == StandardSocketOptions.IP_TOS) {
ProtocolFamily family = Net.isIPv6Available() ?
StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
Net.setSocketOption(fd, family, name, value);
return this;
}
if (name == StandardSocketOptions.SO_REUSEADDR && Net.useExclusiveBind()) {
// SO_REUSEADDR emulated when using exclusive bind
isReuseAddress = (Boolean)value;
return this;
}
// no options that require special handling
Net.setSocketOption(fd, name, value);
return this;
}
}