mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8241072: Reimplement the Legacy DatagramSocket API
Replace the underlying implementations of the java.net.DatagramSocket and java.net.MulticastSocket APIs with simpler and more modern implementations that are easy to maintain and debug. Co-authored-by: Alan Bateman <alan.bateman@oracle.com> Co-authored-by: Chris Hegarty <chris.hegarty@oracle.com> Co-authored-by: Daniel Fuchs <daniel.fuchs@oracle.com> Reviewed-by: alanb, chegar, dfuchs
This commit is contained in:
parent
3930460af5
commit
fad2cf51ba
34 changed files with 1478 additions and 909 deletions
|
@ -28,9 +28,6 @@ package java.net;
|
|||
import java.io.IOException;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import java.nio.channels.MulticastChannel;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The multicast datagram socket class is useful for sending
|
||||
|
@ -135,11 +132,19 @@ import java.util.Set;
|
|||
*/
|
||||
public class MulticastSocket extends DatagramSocket {
|
||||
|
||||
@Override
|
||||
final MulticastSocket delegate() {
|
||||
return (MulticastSocket) super.delegate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used on some platforms to record if an outgoing interface
|
||||
* has been set for this socket.
|
||||
* Create a MulticastSocket that delegates to the given delegate if not null.
|
||||
* @param delegate the delegate, can be null.
|
||||
*/
|
||||
private boolean interfaceSet;
|
||||
MulticastSocket(MulticastSocket delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a multicast socket.
|
||||
|
@ -216,44 +221,9 @@ public class MulticastSocket extends DatagramSocket {
|
|||
* @since 1.4
|
||||
*/
|
||||
public MulticastSocket(SocketAddress bindaddr) throws IOException {
|
||||
super((SocketAddress) null);
|
||||
|
||||
// No further initialization when this is a DatagramChannel socket adaptor
|
||||
if (this instanceof sun.nio.ch.DatagramSocketAdaptor)
|
||||
return;
|
||||
|
||||
// Enable SO_REUSEADDR before binding
|
||||
setReuseAddress(true);
|
||||
|
||||
if (bindaddr != null) {
|
||||
try {
|
||||
bind(bindaddr);
|
||||
} finally {
|
||||
if (!isBound()) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
this(createDelegate(bindaddr, MulticastSocket.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* The lock on the socket's TTL. This is for set/getTTL and
|
||||
* send(packet,ttl).
|
||||
*/
|
||||
private Object ttlLock = new Object();
|
||||
|
||||
/**
|
||||
* The lock on the socket's interface - used by setInterface
|
||||
* and getInterface
|
||||
*/
|
||||
private Object infLock = new Object();
|
||||
|
||||
/**
|
||||
* The "last" interface set by setInterface on this MulticastSocket
|
||||
*/
|
||||
private InetAddress infAddress = null;
|
||||
|
||||
|
||||
/**
|
||||
* Set the default time-to-live for multicast packets sent out
|
||||
* on this {@code MulticastSocket} in order to control the
|
||||
|
@ -271,9 +241,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
@Deprecated
|
||||
public void setTTL(byte ttl) throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
getImpl().setTTL(ttl);
|
||||
delegate().setTTL(ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -297,12 +265,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
* @since 1.2
|
||||
*/
|
||||
public void setTimeToLive(int ttl) throws IOException {
|
||||
if (ttl < 0 || ttl > 255) {
|
||||
throw new IllegalArgumentException("ttl out of range");
|
||||
}
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
getImpl().setTimeToLive(ttl);
|
||||
delegate().setTimeToLive(ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -318,9 +281,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
@Deprecated
|
||||
public byte getTTL() throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
return getImpl().getTTL();
|
||||
return delegate().getTTL();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -333,9 +294,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
* @since 1.2
|
||||
*/
|
||||
public int getTimeToLive() throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
return getImpl().getTimeToLive();
|
||||
return delegate().getTimeToLive();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -359,31 +318,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
@Deprecated(since="14")
|
||||
public void joinGroup(InetAddress mcastaddr) throws IOException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket is closed");
|
||||
}
|
||||
|
||||
checkAddress(mcastaddr, "joinGroup");
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkMulticast(mcastaddr);
|
||||
}
|
||||
|
||||
if (!mcastaddr.isMulticastAddress()) {
|
||||
throw new SocketException("Not a multicast address");
|
||||
}
|
||||
|
||||
/**
|
||||
* required for some platforms where it's not possible to join
|
||||
* a group without setting the interface first.
|
||||
*/
|
||||
NetworkInterface defaultInterface = NetworkInterface.getDefault();
|
||||
|
||||
if (!interfaceSet && defaultInterface != null) {
|
||||
setNetworkInterface(defaultInterface);
|
||||
}
|
||||
|
||||
getImpl().join(mcastaddr);
|
||||
delegate().joinGroup(mcastaddr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -406,21 +341,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
@Deprecated(since="14")
|
||||
public void leaveGroup(InetAddress mcastaddr) throws IOException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket is closed");
|
||||
}
|
||||
|
||||
checkAddress(mcastaddr, "leaveGroup");
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkMulticast(mcastaddr);
|
||||
}
|
||||
|
||||
if (!mcastaddr.isMulticastAddress()) {
|
||||
throw new SocketException("Not a multicast address");
|
||||
}
|
||||
|
||||
getImpl().leave(mcastaddr);
|
||||
delegate().leaveGroup(mcastaddr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -452,26 +373,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
|
||||
throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
|
||||
if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("Unsupported address type");
|
||||
|
||||
if (oldImpl)
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup");
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
|
||||
}
|
||||
|
||||
if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
|
||||
throw new SocketException("Not a multicast address");
|
||||
}
|
||||
|
||||
getImpl().joinGroup(mcastaddr, netIf);
|
||||
delegate().joinGroup(mcastaddr, netIf);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -500,26 +402,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
|
||||
throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
|
||||
if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException("Unsupported address type");
|
||||
|
||||
if (oldImpl)
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup");
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
|
||||
}
|
||||
|
||||
if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
|
||||
throw new SocketException("Not a multicast address");
|
||||
}
|
||||
|
||||
getImpl().leaveGroup(mcastaddr, netIf);
|
||||
delegate().leaveGroup(mcastaddr, netIf);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -537,15 +420,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
@Deprecated(since="14")
|
||||
public void setInterface(InetAddress inf) throws SocketException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket is closed");
|
||||
}
|
||||
checkAddress(inf, "setInterface");
|
||||
synchronized (infLock) {
|
||||
getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
|
||||
infAddress = inf;
|
||||
interfaceSet = true;
|
||||
}
|
||||
delegate().setInterface(inf);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -565,53 +440,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
@Deprecated(since="14")
|
||||
public InetAddress getInterface() throws SocketException {
|
||||
if (isClosed()) {
|
||||
throw new SocketException("Socket is closed");
|
||||
}
|
||||
synchronized (infLock) {
|
||||
InetAddress ia =
|
||||
(InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
|
||||
|
||||
/**
|
||||
* No previous setInterface or interface can be
|
||||
* set using setNetworkInterface
|
||||
*/
|
||||
if (infAddress == null) {
|
||||
return ia;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same interface set with setInterface?
|
||||
*/
|
||||
if (ia.equals(infAddress)) {
|
||||
return ia;
|
||||
}
|
||||
|
||||
/**
|
||||
* Different InetAddress from what we set with setInterface
|
||||
* so enumerate the current interface to see if the
|
||||
* address set by setInterface is bound to this interface.
|
||||
*/
|
||||
try {
|
||||
NetworkInterface ni = NetworkInterface.getByInetAddress(ia);
|
||||
Enumeration<InetAddress> addrs = ni.getInetAddresses();
|
||||
while (addrs.hasMoreElements()) {
|
||||
InetAddress addr = addrs.nextElement();
|
||||
if (addr.equals(infAddress)) {
|
||||
return infAddress;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No match so reset infAddress to indicate that the
|
||||
* interface has changed via means
|
||||
*/
|
||||
infAddress = null;
|
||||
return ia;
|
||||
} catch (Exception e) {
|
||||
return ia;
|
||||
}
|
||||
}
|
||||
return delegate().getInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -626,12 +455,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
public void setNetworkInterface(NetworkInterface netIf)
|
||||
throws SocketException {
|
||||
|
||||
synchronized (infLock) {
|
||||
getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf);
|
||||
infAddress = null;
|
||||
interfaceSet = true;
|
||||
}
|
||||
delegate().setNetworkInterface(netIf);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -646,15 +470,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
* @since 1.4
|
||||
*/
|
||||
public NetworkInterface getNetworkInterface() throws SocketException {
|
||||
NetworkInterface ni
|
||||
= (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
|
||||
if (ni == null) {
|
||||
InetAddress[] addrs = new InetAddress[1];
|
||||
addrs[0] = InetAddress.anyLocalAddress();
|
||||
return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
|
||||
} else {
|
||||
return ni;
|
||||
}
|
||||
return delegate().getNetworkInterface();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -678,7 +494,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
@Deprecated(since="14")
|
||||
public void setLoopbackMode(boolean disable) throws SocketException {
|
||||
getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable));
|
||||
delegate().setLoopbackMode(disable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -694,7 +510,7 @@ public class MulticastSocket extends DatagramSocket {
|
|||
*/
|
||||
@Deprecated(since="14")
|
||||
public boolean getLoopbackMode() throws SocketException {
|
||||
return ((Boolean)getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue();
|
||||
return delegate().getLoopbackMode();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -755,60 +571,6 @@ public class MulticastSocket extends DatagramSocket {
|
|||
@Deprecated
|
||||
public void send(DatagramPacket p, byte ttl)
|
||||
throws IOException {
|
||||
if (isClosed())
|
||||
throw new SocketException("Socket is closed");
|
||||
synchronized(ttlLock) {
|
||||
synchronized(p) {
|
||||
InetAddress packetAddress = p.getAddress();
|
||||
int packetPort = p.getPort();
|
||||
checkAddress(packetAddress, "send");
|
||||
if (connectState == ST_NOT_CONNECTED) {
|
||||
if (packetAddress == null) {
|
||||
throw new IllegalArgumentException("Address not set");
|
||||
}
|
||||
if (packetPort < 0 || packetPort > 0xFFFF)
|
||||
throw new IllegalArgumentException("port out of range:" + packetPort);
|
||||
// Security manager makes sure that the multicast address
|
||||
// is allowed one and that the ttl used is less
|
||||
// than the allowed maxttl.
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
if (packetAddress.isMulticastAddress()) {
|
||||
security.checkMulticast(packetAddress, ttl);
|
||||
} else {
|
||||
security.checkConnect(packetAddress.getHostAddress(),
|
||||
packetPort);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// we're connected
|
||||
if (packetAddress == null) {
|
||||
p.setAddress(connectedAddress);
|
||||
p.setPort(connectedPort);
|
||||
} else if ((!packetAddress.equals(connectedAddress)) ||
|
||||
packetPort != connectedPort) {
|
||||
throw new IllegalArgumentException("connected address and packet address" +
|
||||
" differ");
|
||||
}
|
||||
}
|
||||
byte dttl = getTTL();
|
||||
try {
|
||||
if (ttl != dttl) {
|
||||
// set the ttl
|
||||
getImpl().setTTL(ttl);
|
||||
}
|
||||
if (packetPort == 0) {
|
||||
throw new SocketException("Can't send to port 0");
|
||||
}
|
||||
// call the datagram method to send
|
||||
getImpl().send(p);
|
||||
} finally {
|
||||
// set it back to default
|
||||
if (ttl != dttl) {
|
||||
getImpl().setTTL(dttl);
|
||||
}
|
||||
}
|
||||
} // synch p
|
||||
} //synch ttl
|
||||
} //method
|
||||
delegate().send(p, ttl);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue