Path: blob/master/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java
41159 views
/*1* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.ch;2627import java.io.IOException;28import java.net.InetAddress;29import java.net.InetSocketAddress;30import java.net.ServerSocket;31import java.net.Socket;32import java.net.SocketAddress;33import java.net.SocketException;34import java.net.SocketOption;35import java.net.StandardSocketOptions;36import java.nio.channels.IllegalBlockingModeException;37import java.nio.channels.ServerSocketChannel;38import java.nio.channels.SocketChannel;39import java.security.AccessController;40import java.security.PrivilegedActionException;41import java.security.PrivilegedExceptionAction;42import java.util.Set;4344import static java.util.concurrent.TimeUnit.MILLISECONDS;454647// Make a server-socket channel look like a server socket.48//49// The methods in this class are defined in exactly the same order as in50// java.net.ServerSocket so as to simplify tracking future changes to that51// class.52//5354class ServerSocketAdaptor // package-private55extends ServerSocket56{57// The channel being adapted58private final ServerSocketChannelImpl ssc;5960// Timeout "option" value for accepts61private volatile int timeout;6263@SuppressWarnings("removal")64static ServerSocket create(ServerSocketChannelImpl ssc) {65PrivilegedExceptionAction<ServerSocket> pa = () -> new ServerSocketAdaptor(ssc);66try {67return AccessController.doPrivileged(pa);68} catch (PrivilegedActionException pae) {69throw new InternalError("Should not reach here", pae);70}71}7273private ServerSocketAdaptor(ServerSocketChannelImpl ssc) {74super(DummySocketImpl.create());75this.ssc = ssc;76}7778@Override79public void bind(SocketAddress local) throws IOException {80bind(local, 50);81}8283@Override84public void bind(SocketAddress local, int backlog) throws IOException {85if (local == null)86local = new InetSocketAddress(0);87try {88ssc.bind(local, backlog);89} catch (Exception x) {90Net.translateException(x);91}92}9394@Override95public InetAddress getInetAddress() {96SocketAddress local = ssc.localAddress();97if (local == null) {98return null;99} else {100return Net.getRevealedLocalAddress(local).getAddress();101}102}103104@Override105public int getLocalPort() {106InetSocketAddress local = (InetSocketAddress) ssc.localAddress();107if (local == null) {108return -1;109} else {110return local.getPort();111}112}113114@Override115public Socket accept() throws IOException {116SocketChannel sc = null;117try {118int timeout = this.timeout;119if (timeout > 0) {120long nanos = MILLISECONDS.toNanos(timeout);121sc = ssc.blockingAccept(nanos);122} else {123// accept connection if possible when non-blocking (to preserve124// long standing behavior)125sc = ssc.accept();126if (sc == null) {127throw new IllegalBlockingModeException();128}129}130} catch (Exception e) {131Net.translateException(e);132}133return sc.socket();134}135136@Override137public void close() throws IOException {138ssc.close();139}140141@Override142public ServerSocketChannel getChannel() {143return ssc;144}145146@Override147public boolean isBound() {148return ssc.isBound();149}150151@Override152public boolean isClosed() {153return !ssc.isOpen();154}155156@Override157public void setSoTimeout(int timeout) throws SocketException {158if (!ssc.isOpen())159throw new SocketException("Socket is closed");160if (timeout < 0)161throw new IllegalArgumentException("timeout < 0");162this.timeout = timeout;163}164165@Override166public int getSoTimeout() throws SocketException {167if (!ssc.isOpen())168throw new SocketException("Socket is closed");169return timeout;170}171172@Override173public void setReuseAddress(boolean on) throws SocketException {174try {175ssc.setOption(StandardSocketOptions.SO_REUSEADDR, on);176} catch (IOException x) {177Net.translateToSocketException(x);178}179}180181@Override182public boolean getReuseAddress() throws SocketException {183try {184return ssc.getOption(StandardSocketOptions.SO_REUSEADDR).booleanValue();185} catch (IOException x) {186Net.translateToSocketException(x);187return false; // Never happens188}189}190191@Override192public String toString() {193if (!isBound())194return "ServerSocket[unbound]";195return "ServerSocket[addr=" + getInetAddress() +196",localport=" + getLocalPort() + "]";197}198199@Override200public void setReceiveBufferSize(int size) throws SocketException {201// size 0 valid for ServerSocketChannel, invalid for ServerSocket202if (size <= 0)203throw new IllegalArgumentException("size cannot be 0 or negative");204try {205ssc.setOption(StandardSocketOptions.SO_RCVBUF, size);206} catch (IOException x) {207Net.translateToSocketException(x);208}209}210211@Override212public int getReceiveBufferSize() throws SocketException {213try {214return ssc.getOption(StandardSocketOptions.SO_RCVBUF).intValue();215} catch (IOException x) {216Net.translateToSocketException(x);217return -1; // Never happens218}219}220221@Override222public <T> ServerSocket setOption(SocketOption<T> name, T value) throws IOException {223ssc.setOption(name, value);224return this;225}226227@Override228public <T> T getOption(SocketOption<T> name) throws IOException {229return ssc.getOption(name);230}231232@Override233public Set<SocketOption<?>> supportedOptions() {234return ssc.supportedOptions();235}236}237238239