src/jdk.net/share/classes/jdk/net/Sockets.java

Print this page
rev 14282 : 8044773: Refactor jdk.net API so that it can be moved out of the base module
Reviewed-by:


  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.net;
  27 
  28 import java.net.*;
  29 import java.io.IOException;
  30 import java.io.FileDescriptor;
  31 import java.security.PrivilegedAction;
  32 import java.security.AccessController;
  33 import java.lang.reflect.Field;
  34 import java.util.Set;
  35 import java.util.HashSet;
  36 import java.util.HashMap;
  37 import java.util.Collections;
  38 import sun.net.ExtendedOptionsImpl;




  39 
  40 /**
  41  * Defines static methods to set and get socket options defined by the
  42  * {@link java.net.SocketOption} interface. All of the standard options defined
  43  * by {@link java.net.Socket}, {@link java.net.ServerSocket}, and
  44  * {@link java.net.DatagramSocket} can be set this way, as well as additional
  45  * or platform specific options supported by each socket type.
  46  * <p>
  47  * The {@link #supportedOptions(Class)} method can be called to determine
  48  * the complete set of options available (per socket type) on the
  49  * current system.
  50  * <p>
  51  * When a security manager is installed, some non-standard socket options
  52  * may require a security permission before being set or get.
  53  * The details are specified in {@link ExtendedSocketOptions}. No permission
  54  * is required for {@link java.net.StandardSocketOptions}.
  55  *
  56  * @see java.nio.channels.NetworkChannel
  57  */
  58 public class Sockets {
  59 
  60     private static final HashMap<Class<?>,Set<SocketOption<?>>>
  61         options = new HashMap<>();
  62 
  63     static {
  64         initOptionSets();
  65     }
  66 
  67     private Sockets() {}
  68 
  69     /**
  70      * Sets the value of a socket option on a {@link java.net.Socket}
  71      *
  72      * @param s the socket
  73      * @param name The socket option
  74      * @param value The value of the socket option. May be null for some
  75      *              options.
  76      *
  77      * @throws UnsupportedOperationException if the socket does not support
  78      *         the option.
  79      *
  80      * @throws IllegalArgumentException if the value is not valid for
  81      *         the option.
  82      *
  83      * @throws IOException if an I/O error occurs, or socket is closed.
  84      *
  85      * @throws SecurityException if a security manager is set and the


 242         }
 243         return set;
 244     }
 245 
 246     private static void checkValueType(Object value, Class<?> type) {
 247         if (!type.isAssignableFrom(value.getClass())) {
 248             String s = "Found: " + value.getClass().toString() + " Expected: "
 249                         + type.toString();
 250             throw new IllegalArgumentException(s);
 251         }
 252     }
 253 
 254     private static volatile boolean checkedReusePort;
 255     private static volatile boolean isReusePortAvailable;
 256 
 257     /**
 258      * Tells whether SO_REUSEPORT is supported.
 259      */
 260     static boolean isReusePortAvailable() {
 261         if (!checkedReusePort) {
 262             isReusePortAvailable = isReusePortAvailable0();

 263             checkedReusePort = true;
 264         }
 265         return isReusePortAvailable;
 266     }
 267 
 268     private static void initOptionSets() {
 269         boolean flowsupported = ExtendedOptionsImpl.flowSupported();

 270         boolean reuseportsupported = isReusePortAvailable();
 271         // Socket
 272 
 273         Set<SocketOption<?>> set = new HashSet<>();
 274         set.add(StandardSocketOptions.SO_KEEPALIVE);
 275         set.add(StandardSocketOptions.SO_SNDBUF);
 276         set.add(StandardSocketOptions.SO_RCVBUF);
 277         set.add(StandardSocketOptions.SO_REUSEADDR);
 278         if (reuseportsupported) {
 279             set.add(StandardSocketOptions.SO_REUSEPORT);
 280         }
 281         set.add(StandardSocketOptions.SO_LINGER);
 282         set.add(StandardSocketOptions.IP_TOS);
 283         set.add(StandardSocketOptions.TCP_NODELAY);
 284         if (flowsupported) {
 285             set.add(ExtendedSocketOptions.SO_FLOW_SLA);
 286         }
 287         set = Collections.unmodifiableSet(set);
 288         options.put(Socket.class, set);
 289 


 316         options.put(DatagramSocket.class, set);
 317 
 318         // MulticastSocket
 319 
 320         set = new HashSet<>();
 321         set.add(StandardSocketOptions.SO_SNDBUF);
 322         set.add(StandardSocketOptions.SO_RCVBUF);
 323         set.add(StandardSocketOptions.SO_REUSEADDR);
 324         if (reuseportsupported) {
 325             set.add(StandardSocketOptions.SO_REUSEPORT);
 326         }
 327         set.add(StandardSocketOptions.IP_TOS);
 328         set.add(StandardSocketOptions.IP_MULTICAST_IF);
 329         set.add(StandardSocketOptions.IP_MULTICAST_TTL);
 330         set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
 331         if (flowsupported) {
 332             set.add(ExtendedSocketOptions.SO_FLOW_SLA);
 333         }
 334         set = Collections.unmodifiableSet(set);
 335         options.put(MulticastSocket.class, set);
 336     }
 337 
 338     private static native boolean isReusePortAvailable0();

 339 }


  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.net;
  27 
  28 import java.net.*;
  29 import java.io.IOException;







  30 import java.util.Collections;
  31 import java.util.HashMap;
  32 import java.util.HashSet;
  33 import java.util.Map;
  34 import java.util.Set;
  35 import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
  36 
  37 /**
  38  * Defines static methods to set and get socket options defined by the
  39  * {@link java.net.SocketOption} interface. All of the standard options defined
  40  * by {@link java.net.Socket}, {@link java.net.ServerSocket}, and
  41  * {@link java.net.DatagramSocket} can be set this way, as well as additional
  42  * or platform specific options supported by each socket type.
  43  * <p>
  44  * The {@link #supportedOptions(Class)} method can be called to determine
  45  * the complete set of options available (per socket type) on the
  46  * current system.
  47  * <p>
  48  * When a security manager is installed, some non-standard socket options
  49  * may require a security permission before being set or get.
  50  * The details are specified in {@link ExtendedSocketOptions}. No permission
  51  * is required for {@link java.net.StandardSocketOptions}.
  52  *
  53  * @see java.nio.channels.NetworkChannel
  54  */
  55 public class Sockets {
  56 
  57     private static final Map<Class<?>,Set<SocketOption<?>>>
  58             options = optionSets();




  59 
  60     private Sockets() {}
  61 
  62     /**
  63      * Sets the value of a socket option on a {@link java.net.Socket}
  64      *
  65      * @param s the socket
  66      * @param name The socket option
  67      * @param value The value of the socket option. May be null for some
  68      *              options.
  69      *
  70      * @throws UnsupportedOperationException if the socket does not support
  71      *         the option.
  72      *
  73      * @throws IllegalArgumentException if the value is not valid for
  74      *         the option.
  75      *
  76      * @throws IOException if an I/O error occurs, or socket is closed.
  77      *
  78      * @throws SecurityException if a security manager is set and the


 235         }
 236         return set;
 237     }
 238 
 239     private static void checkValueType(Object value, Class<?> type) {
 240         if (!type.isAssignableFrom(value.getClass())) {
 241             String s = "Found: " + value.getClass().toString() + " Expected: "
 242                         + type.toString();
 243             throw new IllegalArgumentException(s);
 244         }
 245     }
 246 
 247     private static volatile boolean checkedReusePort;
 248     private static volatile boolean isReusePortAvailable;
 249 
 250     /**
 251      * Tells whether SO_REUSEPORT is supported.
 252      */
 253     static boolean isReusePortAvailable() {
 254         if (!checkedReusePort) {
 255             Set<SocketOption<?>> s = new Socket().supportedOptions();
 256             isReusePortAvailable = s.contains(StandardSocketOptions.SO_REUSEPORT);
 257             checkedReusePort = true;
 258         }
 259         return isReusePortAvailable;
 260     }
 261 
 262     private static Map<Class<?>,Set<SocketOption<?>>> optionSets() {
 263         Map<Class<?>,Set<SocketOption<?>>> options = new HashMap<>();
 264         boolean flowsupported = PlatformSocketOptions.get().flowSupported();
 265         boolean reuseportsupported = isReusePortAvailable();
 266         // Socket
 267 
 268         Set<SocketOption<?>> set = new HashSet<>();
 269         set.add(StandardSocketOptions.SO_KEEPALIVE);
 270         set.add(StandardSocketOptions.SO_SNDBUF);
 271         set.add(StandardSocketOptions.SO_RCVBUF);
 272         set.add(StandardSocketOptions.SO_REUSEADDR);
 273         if (reuseportsupported) {
 274             set.add(StandardSocketOptions.SO_REUSEPORT);
 275         }
 276         set.add(StandardSocketOptions.SO_LINGER);
 277         set.add(StandardSocketOptions.IP_TOS);
 278         set.add(StandardSocketOptions.TCP_NODELAY);
 279         if (flowsupported) {
 280             set.add(ExtendedSocketOptions.SO_FLOW_SLA);
 281         }
 282         set = Collections.unmodifiableSet(set);
 283         options.put(Socket.class, set);
 284 


 311         options.put(DatagramSocket.class, set);
 312 
 313         // MulticastSocket
 314 
 315         set = new HashSet<>();
 316         set.add(StandardSocketOptions.SO_SNDBUF);
 317         set.add(StandardSocketOptions.SO_RCVBUF);
 318         set.add(StandardSocketOptions.SO_REUSEADDR);
 319         if (reuseportsupported) {
 320             set.add(StandardSocketOptions.SO_REUSEPORT);
 321         }
 322         set.add(StandardSocketOptions.IP_TOS);
 323         set.add(StandardSocketOptions.IP_MULTICAST_IF);
 324         set.add(StandardSocketOptions.IP_MULTICAST_TTL);
 325         set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
 326         if (flowsupported) {
 327             set.add(ExtendedSocketOptions.SO_FLOW_SLA);
 328         }
 329         set = Collections.unmodifiableSet(set);
 330         options.put(MulticastSocket.class, set);

 331 
 332         return Collections.unmodifiableMap(options);
 333     }
 334 }