jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java
changeset 1152 29d6145d1097
parent 715 f16baef3a20e
child 5506 202f599c92aa
equal deleted inserted replaced
1151:4070cecdb99d 1152:29d6145d1097
    52 {
    52 {
    53 
    53 
    54     // The channel being adapted
    54     // The channel being adapted
    55     private final SocketChannelImpl sc;
    55     private final SocketChannelImpl sc;
    56 
    56 
    57     // Option adaptor object, created on demand
       
    58     private volatile OptionAdaptor opts = null;
       
    59 
       
    60     // Timeout "option" value for reads
    57     // Timeout "option" value for reads
    61     private volatile int timeout = 0;
    58     private volatile int timeout = 0;
    62 
       
    63     // Traffic-class/Type-of-service
       
    64     private volatile int trafficClass = 0;
       
    65 
       
    66 
    59 
    67     // ## super will create a useless impl
    60     // ## super will create a useless impl
    68     private SocketAdaptor(SocketChannelImpl sc) {
    61     private SocketAdaptor(SocketChannelImpl sc) {
    69         this.sc = sc;
    62         this.sc = sc;
    70     }
    63     }
   143 
   136 
   144     }
   137     }
   145 
   138 
   146     public void bind(SocketAddress local) throws IOException {
   139     public void bind(SocketAddress local) throws IOException {
   147         try {
   140         try {
   148             if (local == null)
       
   149                 local = new InetSocketAddress(0);
       
   150             sc.bind(local);
   141             sc.bind(local);
   151         } catch (Exception x) {
   142         } catch (Exception x) {
   152             Net.translateException(x);
   143             Net.translateException(x);
   153         }
   144         }
   154     }
   145     }
   155 
   146 
   156     public InetAddress getInetAddress() {
   147     public InetAddress getInetAddress() {
   157         if (!sc.isConnected())
   148         SocketAddress remote = sc.remoteAddress();
       
   149         if (remote == null) {
   158             return null;
   150             return null;
   159         return Net.asInetSocketAddress(sc.remoteAddress()).getAddress();
   151         } else {
       
   152             return ((InetSocketAddress)remote).getAddress();
       
   153         }
   160     }
   154     }
   161 
   155 
   162     public InetAddress getLocalAddress() {
   156     public InetAddress getLocalAddress() {
   163         if (!sc.isBound())
   157         if (sc.isOpen()) {
   164             return new InetSocketAddress(0).getAddress();
   158             SocketAddress local = sc.localAddress();
   165         return Net.asInetSocketAddress(sc.localAddress()).getAddress();
   159             if (local != null)
       
   160                 return ((InetSocketAddress)local).getAddress();
       
   161         }
       
   162         return new InetSocketAddress(0).getAddress();
   166     }
   163     }
   167 
   164 
   168     public int getPort() {
   165     public int getPort() {
   169         if (!sc.isConnected())
   166         SocketAddress remote = sc.remoteAddress();
       
   167         if (remote == null) {
   170             return 0;
   168             return 0;
   171         return Net.asInetSocketAddress(sc.remoteAddress()).getPort();
   169         } else {
       
   170             return ((InetSocketAddress)remote).getPort();
       
   171         }
   172     }
   172     }
   173 
   173 
   174     public int getLocalPort() {
   174     public int getLocalPort() {
   175         if (!sc.isBound())
   175         SocketAddress local = sc.localAddress();
       
   176         if (local == null) {
   176             return -1;
   177             return -1;
   177         return Net.asInetSocketAddress(sc.localAddress()).getPort();
   178         } else {
       
   179             return ((InetSocketAddress)local).getPort();
       
   180         }
   178     }
   181     }
   179 
   182 
   180     private class SocketInputStream
   183     private class SocketInputStream
   181         extends ChannelInputStream
   184         extends ChannelInputStream
   182     {
   185     {
   274             throw (IOException)e.getException();
   277             throw (IOException)e.getException();
   275         }
   278         }
   276         return os;
   279         return os;
   277     }
   280     }
   278 
   281 
   279     private OptionAdaptor opts() {
   282     private void setBooleanOption(SocketOption<Boolean> name, boolean value)
   280         if (opts == null)
   283         throws SocketException
   281             opts = new OptionAdaptor(sc);
   284     {
   282         return opts;
   285         try {
       
   286             sc.setOption(name, value);
       
   287         } catch (IOException x) {
       
   288             Net.translateToSocketException(x);
       
   289         }
       
   290     }
       
   291 
       
   292     private void setIntOption(SocketOption<Integer> name, int value)
       
   293         throws SocketException
       
   294     {
       
   295         try {
       
   296             sc.setOption(name, value);
       
   297         } catch (IOException x) {
       
   298             Net.translateToSocketException(x);
       
   299         }
       
   300     }
       
   301 
       
   302     private boolean getBooleanOption(SocketOption<Boolean> name) throws SocketException {
       
   303         try {
       
   304             return sc.getOption(name).booleanValue();
       
   305         } catch (IOException x) {
       
   306             Net.translateToSocketException(x);
       
   307             return false;       // keep compiler happy
       
   308         }
       
   309     }
       
   310 
       
   311     private int getIntOption(SocketOption<Integer> name) throws SocketException {
       
   312         try {
       
   313             return sc.getOption(name).intValue();
       
   314         } catch (IOException x) {
       
   315             Net.translateToSocketException(x);
       
   316             return -1;          // keep compiler happy
       
   317         }
   283     }
   318     }
   284 
   319 
   285     public void setTcpNoDelay(boolean on) throws SocketException {
   320     public void setTcpNoDelay(boolean on) throws SocketException {
   286         opts().setTcpNoDelay(on);
   321         setBooleanOption(StandardSocketOption.TCP_NODELAY, on);
   287     }
   322     }
   288 
   323 
   289     public boolean getTcpNoDelay() throws SocketException {
   324     public boolean getTcpNoDelay() throws SocketException {
   290         return opts().getTcpNoDelay();
   325         return getBooleanOption(StandardSocketOption.TCP_NODELAY);
   291     }
   326     }
   292 
   327 
   293     public void setSoLinger(boolean on, int linger) throws SocketException {
   328     public void setSoLinger(boolean on, int linger) throws SocketException {
   294         opts().setSoLinger(on, linger);
   329         if (!on)
       
   330             linger = -1;
       
   331         setIntOption(StandardSocketOption.SO_LINGER, linger);
   295     }
   332     }
   296 
   333 
   297     public int getSoLinger() throws SocketException {
   334     public int getSoLinger() throws SocketException {
   298         return opts().getSoLinger();
   335         return getIntOption(StandardSocketOption.SO_LINGER);
   299     }
   336     }
   300 
   337 
   301     public void sendUrgentData(int data) throws IOException {
   338     public void sendUrgentData(int data) throws IOException {
   302         throw new SocketException("Urgent data not supported");
   339         throw new SocketException("Urgent data not supported");
   303     }
   340     }
   304 
   341 
   305     public void setOOBInline(boolean on) throws SocketException {
   342     public void setOOBInline(boolean on) throws SocketException {
   306         opts().setOOBInline(on);
   343         setBooleanOption(ExtendedSocketOption.SO_OOBINLINE, on);
   307     }
   344     }
   308 
   345 
   309     public boolean getOOBInline() throws SocketException {
   346     public boolean getOOBInline() throws SocketException {
   310         return opts().getOOBInline();
   347         return getBooleanOption(ExtendedSocketOption.SO_OOBINLINE);
   311     }
   348     }
   312 
   349 
   313     public void setSoTimeout(int timeout) throws SocketException {
   350     public void setSoTimeout(int timeout) throws SocketException {
   314         if (timeout < 0)
   351         if (timeout < 0)
   315             throw new IllegalArgumentException("timeout can't be negative");
   352             throw new IllegalArgumentException("timeout can't be negative");
   319     public int getSoTimeout() throws SocketException {
   356     public int getSoTimeout() throws SocketException {
   320         return timeout;
   357         return timeout;
   321     }
   358     }
   322 
   359 
   323     public void setSendBufferSize(int size) throws SocketException {
   360     public void setSendBufferSize(int size) throws SocketException {
   324         opts().setSendBufferSize(size);
   361         // size 0 valid for SocketChannel, invalid for Socket
       
   362         if (size <= 0)
       
   363             throw new IllegalArgumentException("Invalid send size");
       
   364         setIntOption(StandardSocketOption.SO_SNDBUF, size);
   325     }
   365     }
   326 
   366 
   327     public int getSendBufferSize() throws SocketException {
   367     public int getSendBufferSize() throws SocketException {
   328         return opts().getSendBufferSize();
   368         return getIntOption(StandardSocketOption.SO_SNDBUF);
   329     }
   369     }
   330 
   370 
   331     public void setReceiveBufferSize(int size) throws SocketException {
   371     public void setReceiveBufferSize(int size) throws SocketException {
   332         opts().setReceiveBufferSize(size);
   372         // size 0 valid for SocketChannel, invalid for Socket
       
   373         if (size <= 0)
       
   374             throw new IllegalArgumentException("Invalid receive size");
       
   375         setIntOption(StandardSocketOption.SO_RCVBUF, size);
   333     }
   376     }
   334 
   377 
   335     public int getReceiveBufferSize() throws SocketException {
   378     public int getReceiveBufferSize() throws SocketException {
   336         return opts().getReceiveBufferSize();
   379         return getIntOption(StandardSocketOption.SO_RCVBUF);
   337     }
   380     }
   338 
   381 
   339     public void setKeepAlive(boolean on) throws SocketException {
   382     public void setKeepAlive(boolean on) throws SocketException {
   340         opts().setKeepAlive(on);
   383         setBooleanOption(StandardSocketOption.SO_KEEPALIVE, on);
   341     }
   384     }
   342 
   385 
   343     public boolean getKeepAlive() throws SocketException {
   386     public boolean getKeepAlive() throws SocketException {
   344         return opts().getKeepAlive();
   387         return getBooleanOption(StandardSocketOption.SO_KEEPALIVE);
   345     }
   388     }
   346 
   389 
   347     public void setTrafficClass(int tc) throws SocketException {
   390     public void setTrafficClass(int tc) throws SocketException {
   348         opts().setTrafficClass(tc);
   391         setIntOption(StandardSocketOption.IP_TOS, tc);
   349         trafficClass = tc;
       
   350     }
   392     }
   351 
   393 
   352     public int getTrafficClass() throws SocketException {
   394     public int getTrafficClass() throws SocketException {
   353         int tc = opts().getTrafficClass();
   395         return getIntOption(StandardSocketOption.IP_TOS);
   354         if (tc < 0) {
       
   355             tc = trafficClass;
       
   356         }
       
   357         return tc;
       
   358     }
   396     }
   359 
   397 
   360     public void setReuseAddress(boolean on) throws SocketException {
   398     public void setReuseAddress(boolean on) throws SocketException {
   361         opts().setReuseAddress(on);
   399         setBooleanOption(StandardSocketOption.SO_REUSEADDR, on);
   362     }
   400     }
   363 
   401 
   364     public boolean getReuseAddress() throws SocketException {
   402     public boolean getReuseAddress() throws SocketException {
   365         return opts().getReuseAddress();
   403         return getBooleanOption(StandardSocketOption.SO_REUSEADDR);
   366     }
   404     }
   367 
   405 
   368     public void close() throws IOException {
   406     public void close() throws IOException {
   369         try {
   407         try {
   370             sc.close();
   408             sc.close();
   400     public boolean isConnected() {
   438     public boolean isConnected() {
   401         return sc.isConnected();
   439         return sc.isConnected();
   402     }
   440     }
   403 
   441 
   404     public boolean isBound() {
   442     public boolean isBound() {
   405         return sc.isBound();
   443         return sc.localAddress() != null;
   406     }
   444     }
   407 
   445 
   408     public boolean isClosed() {
   446     public boolean isClosed() {
   409         return !sc.isOpen();
   447         return !sc.isOpen();
   410     }
   448     }