src/java.base/share/classes/java/nio/channels/SocketChannel.java
branchunixdomainchannels
changeset 58801 119ac9128c1b
parent 47216 71c04702a3d5
child 58847 692de65ab293
--- a/src/java.base/share/classes/java/nio/channels/SocketChannel.java	Fri Oct 25 14:50:16 2019 +0100
+++ b/src/java.base/share/classes/java/nio/channels/SocketChannel.java	Fri Oct 25 15:56:35 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,9 @@
 package java.nio.channels;
 
 import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ProtocolFamily;
+import java.net.StandardProtocolFamily;
 import java.net.Socket;
 import java.net.SocketOption;
 import java.net.SocketAddress;
@@ -36,8 +39,8 @@
 /**
  * A selectable channel for stream-oriented connecting sockets.
  *
- * <p> A socket channel is created by invoking one of the {@link #open open}
- * methods of this class.  It is not possible to create a channel for an arbitrary,
+ * <p> A socket channel is created by invoking one of the open methods of this class.
+ * It is not possible to create a channel for an arbitrary,
  * pre-existing socket. A newly-created socket channel is open but not yet
  * connected.  An attempt to invoke an I/O operation upon an unconnected
  * channel will cause a {@link NotYetConnectedException} to be thrown.  A
@@ -63,8 +66,18 @@
  * channel, then the blocked thread will receive an {@link
  * AsynchronousCloseException}.
  *
+ * <p>Two kinds of socket channel are supported: <i>IP</i> (Internet Protocol) and
+ * <i>unix domain</i> depending on which open method is used to create them and which
+ * subtype of {@link SocketAddress} that they support for local and remote addresses.
+ * <i>IP</i> channels are created using {@link #open()}. They use {@link
+ * InetSocketAddress} addresses and support both IPv4 and IPv6 TCP/IP.
+ * <i>unix domain</i> channels are created using {@link #open(ProtocolFamily)}
+ * with the family parameter set to {@link StandardProtocolFamily#UNIX}.
+ * They use {@link UnixDomainSocketAddress}es and also
+ * do not support the {@link #socket()} method.
+ *
  * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
- * setOption} method. Socket channels support the following options:
+ * setOption} method. <i>IP</i> socket channels support the following options:
  * <blockquote>
  * <table class="striped">
  * <caption style="display:none">Socket options</caption>
@@ -103,6 +116,7 @@
  * </tbody>
  * </table>
  * </blockquote>
+ *
  * Additional (implementation specific) options may also be supported.
  *
  * <p> Socket channels are safe for use by multiple concurrent threads.  They
@@ -113,6 +127,8 @@
  * or write operation while an invocation of one of these methods is in
  * progress will block until that invocation is complete.  </p>
  *
+ * <p><i>Unix domain</i> channels support a subset of the options listed above.
+ *
  * @author Mark Reinhold
  * @author JSR-51 Expert Group
  * @since 1.4
@@ -124,7 +140,7 @@
 {
 
     /**
-     * Initializes a new instance of this class.
+     * Initializes a new <i>IP</i> instance of this class.
      *
      * @param  provider
      *         The provider that created this channel
@@ -134,7 +150,7 @@
     }
 
     /**
-     * Opens a socket channel.
+     * Opens an <i>IP</i> socket channel.
      *
      * <p> The new channel is created by invoking the {@link
      * java.nio.channels.spi.SelectorProvider#openSocketChannel
@@ -151,13 +167,36 @@
     }
 
     /**
-     * Opens a socket channel and connects it to a remote address.
+     * Returns a {@link SocketChannel} of the given {@link ProtocolFamily}.
+     *
+     * @param family the protocol family
+     *
+     * @return a SocketChannel
      *
-     * <p> This convenience method works as if by invoking the {@link #open()}
+     * @throws IOException if an I/O error occurs
+     * @throws UnsupportedAddressTypeException if the protocol family is not supported
+     * @since 14
+     */
+    public static SocketChannel open(ProtocolFamily family) throws IOException {
+        return SelectorProvider.provider().openSocketChannel(family);
+    }
+
+    /**
+     * Opens a socket channel and connects it to a remote address.
+     * Depending on the type of {@link SocketAddress} supplied, the returned object
+     * is an <i>IP</i> or <i>unix domain</i> channel.
+     *
+     * <p> For {@link InetSocketAddress}es this convenience method works as if by invoking the {@link #open()}
      * method, invoking the {@link #connect(SocketAddress) connect} method upon
      * the resulting socket channel, passing it {@code remote}, and then
      * returning that channel.  </p>
      *
+     * <p> For {@link UnixDomainSocketAddress}es it works as if by invoking the {@link
+     * #open(ProtocolFamily)} method with {@link StandardProtocolFamily#UNIX} as parameter,
+     * invoking the {@link #connect(SocketAddress) connect} method upon
+     * the resulting socket channel, passing it {@code remote}, and then
+     * returning that channel.  </p>
+     *
      * @param  remote
      *         The remote address to which the new channel is to be connected
      *
@@ -174,7 +213,7 @@
      *          interrupt status
      *
      * @throws  UnresolvedAddressException
-     *          If the given remote address is not fully resolved
+     *          If the given remote is an InetSocketAddress that is not fully resolved
      *
      * @throws  UnsupportedAddressTypeException
      *          If the type of the given remote address is not supported
@@ -189,7 +228,14 @@
     public static SocketChannel open(SocketAddress remote)
         throws IOException
     {
-        SocketChannel sc = open();
+        SocketChannel sc;
+        if (remote instanceof InetSocketAddress)
+            sc = open();
+        else if (remote instanceof UnixDomainSocketAddress)
+            sc = open(StandardProtocolFamily.UNIX);
+        else
+            throw new UnsupportedAddressTypeException();
+
         try {
             sc.connect(remote);
         } catch (Throwable x) {
@@ -225,6 +271,13 @@
     // -- Socket-specific operations --
 
     /**
+     * {@inheritDoc}
+     *
+     * <p> Note, for <i>Unix domain</i> channels, a file is created in the file-system
+     * with the same name as this channel's bound address. This file persists after
+     * the channel is closed, and must be removed before another channel can bind
+     * to the same name.
+     *
      * @throws  ConnectionPendingException
      *          If a non-blocking connect operation is already in progress on
      *          this channel
@@ -235,7 +288,9 @@
      * @throws  SecurityException
      *          If a security manager has been installed and its
      *          {@link SecurityManager#checkListen checkListen} method denies
-     *          the operation
+     *          the operation for <i>IP</i> channels or for <i>unix domain</i>
+     *          channels, if the security manager denies "read" or "write"
+     *          {@link FilePermission} for the local path.
      *
      * @since 1.7
      */
@@ -297,12 +352,14 @@
     public abstract SocketChannel shutdownOutput() throws IOException;
 
     /**
-     * Retrieves a socket associated with this channel.
+     * Retrieves a socket associated with this channel if it is an <i>IP</i>
+     * channel. The operation is not supported for <i>unix domain</i> channels.
      *
      * <p> The returned object will not declare any public methods that are not
      * declared in the {@link java.net.Socket} class.  </p>
      *
      * @return  A socket associated with this channel
+     * @throws UnsupportedOperationException is this is a Unix domain channel
      */
     public abstract Socket socket();
 
@@ -338,12 +395,17 @@
      * method will block until the connection is established or an I/O error
      * occurs.
      *
-     * <p> This method performs exactly the same security checks as the {@link
-     * java.net.Socket} class.  That is, if a security manager has been
+     * <p> For <i>IP</i> channels, this method performs exactly the same security checks
+     * as the {@link java.net.Socket} class.  That is, if a security manager has been
      * installed then this method verifies that its {@link
      * java.lang.SecurityManager#checkConnect checkConnect} method permits
      * connecting to the address and port number of the given remote endpoint.
      *
+     * <p> For <i>unix domain</i> channels, this method performs a security
+     * manager {@link SecurityManager#checkPermission(Permission)} using
+     * a {@link java.io.FilePermission} constructed with the path from the
+     * destination address and "read,write" as the actions.
+     *
      * <p> This method may be invoked at any time.  If a read or write
      * operation upon this channel is invoked while an invocation of this
      * method is in progress then that operation will first block until this
@@ -379,7 +441,7 @@
      *          interrupt status
      *
      * @throws  UnresolvedAddressException
-     *          If the given remote address is not fully resolved
+     *          If the given remote address is an InetSocketAddress which is not fully resolved
      *
      * @throws  UnsupportedAddressTypeException
      *          If the type of the given remote address is not supported
@@ -451,6 +513,9 @@
      * socket address then the return value from this method is of type {@link
      * java.net.InetSocketAddress}.
      *
+     * <p> Where the channel is bound and connected to a <i>Unix domain</i>
+     * address, the returned address is a {@link UnixDomainSocketAddress}
+     *
      * @return  The remote address; {@code null} if the channel's socket is not
      *          connected
      *
@@ -510,12 +575,17 @@
     /**
      * {@inheritDoc}
      * <p>
-     * If there is a security manager set, its {@code checkConnect} method is
+     * If there is a security manager set and this is an <i>IP</i> channel,
+     * {@code checkConnect} method is
      * called with the local address and {@code -1} as its arguments to see
      * if the operation is allowed. If the operation is not allowed,
      * a {@code SocketAddress} representing the
      * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
      * local port of the channel's socket is returned.
+     * <p>
+     * If there is a security manager set and this is an <i>unix domain</i> channel,
+     * then this returns a {@link UnixDomainSocketAddress} corresponding to the
+     * bound address.
      *
      * @return  The {@code SocketAddress} that the socket is bound to, or the
      *          {@code SocketAddress} representing the loopback address if
@@ -527,5 +597,4 @@
      */
     @Override
     public abstract SocketAddress getLocalAddress() throws IOException;
-
 }