Home | History | Annotate | Download | only in ch
      1 /*
      2  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      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
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     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 sun.nio.ch;
     27 
     28 import java.io.*;
     29 import java.net.*;
     30 import java.nio.channels.*;
     31 
     32 
     33 // Make a server-socket channel look like a server socket.
     34 //
     35 // The methods in this class are defined in exactly the same order as in
     36 // java.net.ServerSocket so as to simplify tracking future changes to that
     37 // class.
     38 //
     39 
     40 public class ServerSocketAdaptor                        // package-private
     41     extends ServerSocket
     42 {
     43 
     44     // The channel being adapted
     45     private final ServerSocketChannelImpl ssc;
     46 
     47     // Timeout "option" value for accepts
     48     private volatile int timeout = 0;
     49 
     50     public static ServerSocket create(ServerSocketChannelImpl ssc) {
     51         try {
     52             return new ServerSocketAdaptor(ssc);
     53         } catch (IOException x) {
     54             throw new Error(x);
     55         }
     56     }
     57 
     58     // ## super will create a useless impl
     59     private ServerSocketAdaptor(ServerSocketChannelImpl ssc)
     60         throws IOException
     61     {
     62         this.ssc = ssc;
     63     }
     64 
     65 
     66     public void bind(SocketAddress local) throws IOException {
     67         bind(local, 50);
     68     }
     69 
     70     public void bind(SocketAddress local, int backlog) throws IOException {
     71         if (local == null)
     72             local = new InetSocketAddress(0);
     73         try {
     74             ssc.bind(local, backlog);
     75         } catch (Exception x) {
     76             Net.translateException(x);
     77         }
     78     }
     79 
     80     public InetAddress getInetAddress() {
     81         if (!ssc.isBound())
     82             return null;
     83         return Net.getRevealedLocalAddress(ssc.localAddress()).getAddress();
     84 
     85     }
     86 
     87     public int getLocalPort() {
     88         if (!ssc.isBound())
     89             return -1;
     90         return Net.asInetSocketAddress(ssc.localAddress()).getPort();
     91     }
     92 
     93 
     94     public Socket accept() throws IOException {
     95         synchronized (ssc.blockingLock()) {
     96             if (!ssc.isBound())
     97                 throw new IllegalBlockingModeException();
     98             try {
     99                 if (timeout == 0) {
    100                     SocketChannel sc = ssc.accept();
    101                     if (sc == null && !ssc.isBlocking())
    102                         throw new IllegalBlockingModeException();
    103                     return sc.socket();
    104                 }
    105 
    106                 ssc.configureBlocking(false);
    107                 try {
    108                     SocketChannel sc;
    109                     if ((sc = ssc.accept()) != null)
    110                         return sc.socket();
    111                     long to = timeout;
    112                     for (;;) {
    113                         if (!ssc.isOpen())
    114                             throw new ClosedChannelException();
    115                         long st = System.currentTimeMillis();
    116                         int result = ssc.poll(Net.POLLIN, to);
    117                         if (result > 0 && ((sc = ssc.accept()) != null))
    118                             return sc.socket();
    119                         to -= System.currentTimeMillis() - st;
    120                         if (to <= 0)
    121                             throw new SocketTimeoutException();
    122                     }
    123                 } finally {
    124                     if (ssc.isOpen())
    125                         ssc.configureBlocking(true);
    126                 }
    127 
    128             } catch (Exception x) {
    129                 Net.translateException(x);
    130                 assert false;
    131                 return null;            // Never happens
    132             }
    133         }
    134     }
    135 
    136     public void close() throws IOException {
    137         ssc.close();
    138     }
    139 
    140     public ServerSocketChannel getChannel() {
    141         return ssc;
    142     }
    143 
    144     public boolean isBound() {
    145         return ssc.isBound();
    146     }
    147 
    148     public boolean isClosed() {
    149         return !ssc.isOpen();
    150     }
    151 
    152     public void setSoTimeout(int timeout) throws SocketException {
    153         this.timeout = timeout;
    154     }
    155 
    156     public int getSoTimeout() throws SocketException {
    157         return timeout;
    158     }
    159 
    160     public void setReuseAddress(boolean on) throws SocketException {
    161         try {
    162             ssc.setOption(StandardSocketOptions.SO_REUSEADDR, on);
    163         } catch (IOException x) {
    164             Net.translateToSocketException(x);
    165         }
    166     }
    167 
    168     public boolean getReuseAddress() throws SocketException {
    169         try {
    170             return ssc.getOption(StandardSocketOptions.SO_REUSEADDR).booleanValue();
    171         } catch (IOException x) {
    172             Net.translateToSocketException(x);
    173             return false;       // Never happens
    174         }
    175     }
    176 
    177     public String toString() {
    178         if (!isBound())
    179             return "ServerSocket[unbound]";
    180         return "ServerSocket[addr=" + getInetAddress() +
    181             //          ",port=" + getPort() +
    182                 ",localport=" + getLocalPort()  + "]";
    183     }
    184 
    185     public void setReceiveBufferSize(int size) throws SocketException {
    186         // size 0 valid for ServerSocketChannel, invalid for ServerSocket
    187         if (size <= 0)
    188             throw new IllegalArgumentException("size cannot be 0 or negative");
    189         try {
    190             ssc.setOption(StandardSocketOptions.SO_RCVBUF, size);
    191         } catch (IOException x) {
    192             Net.translateToSocketException(x);
    193         }
    194     }
    195 
    196     public int getReceiveBufferSize() throws SocketException {
    197         try {
    198             return ssc.getOption(StandardSocketOptions.SO_RCVBUF).intValue();
    199         } catch (IOException x) {
    200             Net.translateToSocketException(x);
    201             return -1;          // Never happens
    202         }
    203     }
    204 
    205 }
    206