src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
changeset 54620 13b67c1420b8
parent 49001 ce06058197a4
child 58899 5573a7098439
equal deleted inserted replaced
54619:b43cc3b9ef40 54620:13b67c1420b8
     1 /*
     1 /*
     2  * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    40 import java.nio.ByteBuffer;
    40 import java.nio.ByteBuffer;
    41 import java.nio.channels.ClosedChannelException;
    41 import java.nio.channels.ClosedChannelException;
    42 import java.nio.channels.DatagramChannel;
    42 import java.nio.channels.DatagramChannel;
    43 import java.nio.channels.IllegalBlockingModeException;
    43 import java.nio.channels.IllegalBlockingModeException;
    44 import java.util.Objects;
    44 import java.util.Objects;
       
    45 import java.util.Set;
    45 
    46 
    46 
    47 
    47 // Make a datagram-socket channel look like a datagram socket.
    48 // Make a datagram-socket channel look like a datagram socket.
    48 //
    49 //
    49 // The methods in this class are defined in exactly the same order as in
    50 // The methods in this class are defined in exactly the same order as in
    50 // java.net.DatagramSocket so as to simplify tracking future changes to that
    51 // java.net.DatagramSocket so as to simplify tracking future changes to that
    51 // class.
    52 // class.
    52 //
    53 //
    53 
    54 
    54 public class DatagramSocketAdaptor
    55 class DatagramSocketAdaptor
    55     extends DatagramSocket
    56     extends DatagramSocket
    56 {
    57 {
    57     // The channel being adapted
    58     // The channel being adapted
    58     private final DatagramChannelImpl dc;
    59     private final DatagramChannelImpl dc;
    59 
    60 
    60     // Timeout "option" value for receives
    61     // Timeout "option" value for receives
    61     private volatile int timeout;
    62     private volatile int timeout;
    62 
    63 
    63     // ## super will create a useless impl
    64     // ## super will create a useless impl
    64     private DatagramSocketAdaptor(DatagramChannelImpl dc) throws IOException {
    65     private DatagramSocketAdaptor(DatagramChannelImpl dc) {
    65         // Invoke the DatagramSocketAdaptor(SocketAddress) constructor,
    66         // Invoke the DatagramSocketAdaptor(SocketAddress) constructor,
    66         // passing a dummy DatagramSocketImpl object to avoid any native
    67         // passing a dummy DatagramSocketImpl object to avoid any native
    67         // resource allocation in super class and invoking our bind method
    68         // resource allocation in super class and invoking our bind method
    68         // before the dc field is initialized.
    69         // before the dc field is initialized.
    69         super(dummyDatagramSocket);
    70         super(dummyDatagramSocket);
    70         this.dc = dc;
    71         this.dc = dc;
    71     }
    72     }
    72 
    73 
    73     public static DatagramSocket create(DatagramChannelImpl dc) {
    74     static DatagramSocket create(DatagramChannelImpl dc) {
    74         try {
    75         return new DatagramSocketAdaptor(dc);
    75             return new DatagramSocketAdaptor(dc);
       
    76         } catch (IOException x) {
       
    77             throw new Error(x);
       
    78         }
       
    79     }
    76     }
    80 
    77 
    81     private void connectInternal(SocketAddress remote)
    78     private void connectInternal(SocketAddress remote)
    82         throws SocketException
    79         throws SocketException
    83     {
    80     {
    94         } catch (Exception x) {
    91         } catch (Exception x) {
    95             Net.translateToSocketException(x);
    92             Net.translateToSocketException(x);
    96         }
    93         }
    97     }
    94     }
    98 
    95 
       
    96     @Override
    99     public void bind(SocketAddress local) throws SocketException {
    97     public void bind(SocketAddress local) throws SocketException {
   100         try {
    98         try {
   101             if (local == null)
    99             if (local == null)
   102                 local = new InetSocketAddress(0);
   100                 local = new InetSocketAddress(0);
   103             dc.bind(local);
   101             dc.bind(local);
   104         } catch (Exception x) {
   102         } catch (Exception x) {
   105             Net.translateToSocketException(x);
   103             Net.translateToSocketException(x);
   106         }
   104         }
   107     }
   105     }
   108 
   106 
       
   107     @Override
   109     public void connect(InetAddress address, int port) {
   108     public void connect(InetAddress address, int port) {
   110         try {
   109         try {
   111             connectInternal(new InetSocketAddress(address, port));
   110             connectInternal(new InetSocketAddress(address, port));
   112         } catch (SocketException x) {
   111         } catch (SocketException x) {
   113             // Yes, j.n.DatagramSocket really does this
   112             // Yes, j.n.DatagramSocket really does this
   114         }
   113         }
   115     }
   114     }
   116 
   115 
       
   116     @Override
   117     public void connect(SocketAddress remote) throws SocketException {
   117     public void connect(SocketAddress remote) throws SocketException {
   118         Objects.requireNonNull(remote, "Address can't be null");
   118         Objects.requireNonNull(remote, "Address can't be null");
   119         connectInternal(remote);
   119         connectInternal(remote);
   120     }
   120     }
   121 
   121 
       
   122     @Override
   122     public void disconnect() {
   123     public void disconnect() {
   123         try {
   124         try {
   124             dc.disconnect();
   125             dc.disconnect();
   125         } catch (IOException x) {
   126         } catch (IOException x) {
   126             throw new Error(x);
   127             throw new Error(x);
   127         }
   128         }
   128     }
   129     }
   129 
   130 
       
   131     @Override
   130     public boolean isBound() {
   132     public boolean isBound() {
   131         return dc.localAddress() != null;
   133         return dc.localAddress() != null;
   132     }
   134     }
   133 
   135 
       
   136     @Override
   134     public boolean isConnected() {
   137     public boolean isConnected() {
   135         return dc.remoteAddress() != null;
   138         return dc.remoteAddress() != null;
   136     }
   139     }
   137 
   140 
       
   141     @Override
   138     public InetAddress getInetAddress() {
   142     public InetAddress getInetAddress() {
   139         InetSocketAddress remote = dc.remoteAddress();
   143         InetSocketAddress remote = dc.remoteAddress();
   140         return (remote != null) ? remote.getAddress() : null;
   144         return (remote != null) ? remote.getAddress() : null;
   141     }
   145     }
   142 
   146 
       
   147     @Override
   143     public int getPort() {
   148     public int getPort() {
   144         InetSocketAddress remote = dc.remoteAddress();
   149         InetSocketAddress remote = dc.remoteAddress();
   145         return (remote != null) ? remote.getPort() : -1;
   150         return (remote != null) ? remote.getPort() : -1;
   146     }
   151     }
   147 
   152 
       
   153     @Override
       
   154     public SocketAddress getRemoteSocketAddress() {
       
   155         return dc.remoteAddress();
       
   156     }
       
   157 
       
   158     @Override
       
   159     public SocketAddress getLocalSocketAddress() {
       
   160         return dc.localAddress();
       
   161     }
       
   162 
       
   163     @Override
   148     public void send(DatagramPacket p) throws IOException {
   164     public void send(DatagramPacket p) throws IOException {
   149         synchronized (dc.blockingLock()) {
   165         synchronized (dc.blockingLock()) {
   150             if (!dc.isBlocking())
   166             if (!dc.isBlocking())
   151                 throw new IllegalBlockingModeException();
   167                 throw new IllegalBlockingModeException();
   152             try {
   168             try {
   196                     throw new SocketTimeoutException();
   212                     throw new SocketTimeoutException();
   197             }
   213             }
   198         }
   214         }
   199     }
   215     }
   200 
   216 
       
   217     @Override
   201     public void receive(DatagramPacket p) throws IOException {
   218     public void receive(DatagramPacket p) throws IOException {
   202         synchronized (dc.blockingLock()) {
   219         synchronized (dc.blockingLock()) {
   203             if (!dc.isBlocking())
   220             if (!dc.isBlocking())
   204                 throw new IllegalBlockingModeException();
   221                 throw new IllegalBlockingModeException();
   205             try {
   222             try {
   215                 Net.translateException(x);
   232                 Net.translateException(x);
   216             }
   233             }
   217         }
   234         }
   218     }
   235     }
   219 
   236 
       
   237     @Override
   220     public InetAddress getLocalAddress() {
   238     public InetAddress getLocalAddress() {
   221         if (isClosed())
   239         if (isClosed())
   222             return null;
   240             return null;
   223         InetSocketAddress local = dc.localAddress();
   241         InetSocketAddress local = dc.localAddress();
   224         if (local == null)
   242         if (local == null)
   233             }
   251             }
   234         }
   252         }
   235         return result;
   253         return result;
   236     }
   254     }
   237 
   255 
       
   256     @Override
   238     public int getLocalPort() {
   257     public int getLocalPort() {
   239         if (isClosed())
   258         if (isClosed())
   240             return -1;
   259             return -1;
   241         try {
   260         try {
   242             InetSocketAddress local = dc.localAddress();
   261             InetSocketAddress local = dc.localAddress();
   246         } catch (Exception x) {
   265         } catch (Exception x) {
   247         }
   266         }
   248         return 0;
   267         return 0;
   249     }
   268     }
   250 
   269 
       
   270     @Override
   251     public void setSoTimeout(int timeout) throws SocketException {
   271     public void setSoTimeout(int timeout) throws SocketException {
       
   272         if (!dc.isOpen())
       
   273             throw new SocketException("Socket is closed");
       
   274         if (timeout < 0)
       
   275             throw new IllegalArgumentException("timeout < 0");
   252         this.timeout = timeout;
   276         this.timeout = timeout;
   253     }
   277     }
   254 
   278 
       
   279     @Override
   255     public int getSoTimeout() throws SocketException {
   280     public int getSoTimeout() throws SocketException {
       
   281         if (!dc.isOpen())
       
   282             throw new SocketException("Socket is closed");
   256         return timeout;
   283         return timeout;
   257     }
   284     }
   258 
   285 
   259     private void setBooleanOption(SocketOption<Boolean> name, boolean value)
   286     private void setBooleanOption(SocketOption<Boolean> name, boolean value)
   260         throws SocketException
   287         throws SocketException
   292             Net.translateToSocketException(x);
   319             Net.translateToSocketException(x);
   293             return -1;          // keep compiler happy
   320             return -1;          // keep compiler happy
   294         }
   321         }
   295     }
   322     }
   296 
   323 
       
   324     @Override
   297     public void setSendBufferSize(int size) throws SocketException {
   325     public void setSendBufferSize(int size) throws SocketException {
   298         if (size <= 0)
   326         if (size <= 0)
   299             throw new IllegalArgumentException("Invalid send size");
   327             throw new IllegalArgumentException("Invalid send size");
   300         setIntOption(StandardSocketOptions.SO_SNDBUF, size);
   328         setIntOption(StandardSocketOptions.SO_SNDBUF, size);
   301     }
   329     }
   302 
   330 
       
   331     @Override
   303     public int getSendBufferSize() throws SocketException {
   332     public int getSendBufferSize() throws SocketException {
   304         return getIntOption(StandardSocketOptions.SO_SNDBUF);
   333         return getIntOption(StandardSocketOptions.SO_SNDBUF);
   305     }
   334     }
   306 
   335 
       
   336     @Override
   307     public void setReceiveBufferSize(int size) throws SocketException {
   337     public void setReceiveBufferSize(int size) throws SocketException {
   308         if (size <= 0)
   338         if (size <= 0)
   309             throw new IllegalArgumentException("Invalid receive size");
   339             throw new IllegalArgumentException("Invalid receive size");
   310         setIntOption(StandardSocketOptions.SO_RCVBUF, size);
   340         setIntOption(StandardSocketOptions.SO_RCVBUF, size);
   311     }
   341     }
   312 
   342 
       
   343     @Override
   313     public int getReceiveBufferSize() throws SocketException {
   344     public int getReceiveBufferSize() throws SocketException {
   314         return getIntOption(StandardSocketOptions.SO_RCVBUF);
   345         return getIntOption(StandardSocketOptions.SO_RCVBUF);
   315     }
   346     }
   316 
   347 
       
   348     @Override
   317     public void setReuseAddress(boolean on) throws SocketException {
   349     public void setReuseAddress(boolean on) throws SocketException {
   318         setBooleanOption(StandardSocketOptions.SO_REUSEADDR, on);
   350         setBooleanOption(StandardSocketOptions.SO_REUSEADDR, on);
   319     }
   351     }
   320 
   352 
       
   353     @Override
   321     public boolean getReuseAddress() throws SocketException {
   354     public boolean getReuseAddress() throws SocketException {
   322         return getBooleanOption(StandardSocketOptions.SO_REUSEADDR);
   355         return getBooleanOption(StandardSocketOptions.SO_REUSEADDR);
   323 
   356 
   324     }
   357     }
   325 
   358 
       
   359     @Override
   326     public void setBroadcast(boolean on) throws SocketException {
   360     public void setBroadcast(boolean on) throws SocketException {
   327         setBooleanOption(StandardSocketOptions.SO_BROADCAST, on);
   361         setBooleanOption(StandardSocketOptions.SO_BROADCAST, on);
   328     }
   362     }
   329 
   363 
       
   364     @Override
   330     public boolean getBroadcast() throws SocketException {
   365     public boolean getBroadcast() throws SocketException {
   331         return getBooleanOption(StandardSocketOptions.SO_BROADCAST);
   366         return getBooleanOption(StandardSocketOptions.SO_BROADCAST);
   332     }
   367     }
   333 
   368 
       
   369     @Override
   334     public void setTrafficClass(int tc) throws SocketException {
   370     public void setTrafficClass(int tc) throws SocketException {
   335         setIntOption(StandardSocketOptions.IP_TOS, tc);
   371         setIntOption(StandardSocketOptions.IP_TOS, tc);
   336     }
   372     }
   337 
   373 
       
   374     @Override
   338     public int getTrafficClass() throws SocketException {
   375     public int getTrafficClass() throws SocketException {
   339         return getIntOption(StandardSocketOptions.IP_TOS);
   376         return getIntOption(StandardSocketOptions.IP_TOS);
   340     }
   377     }
   341 
   378 
       
   379     @Override
   342     public void close() {
   380     public void close() {
   343         try {
   381         try {
   344             dc.close();
   382             dc.close();
   345         } catch (IOException x) {
   383         } catch (IOException x) {
   346             throw new Error(x);
   384             throw new Error(x);
   347         }
   385         }
   348     }
   386     }
   349 
   387 
       
   388     @Override
   350     public boolean isClosed() {
   389     public boolean isClosed() {
   351         return !dc.isOpen();
   390         return !dc.isOpen();
   352     }
   391     }
   353 
   392 
       
   393     @Override
   354     public DatagramChannel getChannel() {
   394     public DatagramChannel getChannel() {
   355         return dc;
   395         return dc;
       
   396     }
       
   397 
       
   398     @Override
       
   399     public <T> DatagramSocket setOption(SocketOption<T> name, T value) throws IOException {
       
   400         dc.setOption(name, value);
       
   401         return this;
       
   402     }
       
   403 
       
   404     @Override
       
   405     public <T> T getOption(SocketOption<T> name) throws IOException {
       
   406         return dc.getOption(name);
       
   407     }
       
   408 
       
   409     @Override
       
   410     public Set<SocketOption<?>> supportedOptions() {
       
   411         return dc.supportedOptions();
   356     }
   412     }
   357 
   413 
   358    /*
   414    /*
   359     * A dummy implementation of DatagramSocketImpl that can be passed to the
   415     * A dummy implementation of DatagramSocketImpl that can be passed to the
   360     * DatagramSocket constructor so that no native resources are allocated in
   416     * DatagramSocket constructor so that no native resources are allocated in