1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.net;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
209902f3494c6d983879d8b9cfe6b1f771cfefe703Elliott Hughesimport java.io.Closeable;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.ServerSocketChannel;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
24933fbbf606268eec9fc430632b8bca7002a833b3Neil Fullerimport libcore.io.IoBridge;
25933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class represents a server-side socket that waits for incoming client
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connections. A {@code ServerSocket} handles the requests and sends back an
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * appropriate reply. The actual tasks that a server socket must accomplish are
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implemented by an internal {@code SocketImpl} instance.
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
329902f3494c6d983879d8b9cfe6b1f771cfefe703Elliott Hughespublic class ServerSocket implements Closeable {
33a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    /**
34a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * The RI specifies that where the caller doesn't give an explicit backlog,
35a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * the default is 50. The OS disagrees, so we need to explicitly call listen(2).
36a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     */
37a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    private static final int DEFAULT_BACKLOG = 50;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    private final SocketImpl impl;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    /**
42a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * @hide internal use only
43a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     */
44a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    public SocketImpl getImpl$() {
45a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        return impl;
46a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    }
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
48a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    static SocketImplFactory factory;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isBound;
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isClosed;
53f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
54933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    private InetAddress localAddress;
55933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
57a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * Constructs a new unbound {@code ServerSocket}.
58f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
59a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * @throws IOException if an error occurs while creating the socket.
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ServerSocket() throws IOException {
62a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        this.impl = factory != null ? factory.createSocketImpl()
63f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                : new PlainServerSocketImpl();
64a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        impl.create(true);
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
687d5a8340b6f50d1d8677463897c3ba499fad3eb8Neil Fuller     * Constructs a new {@code ServerSocket} instance bound to the given {@code port} using a
697d5a8340b6f50d1d8677463897c3ba499fad3eb8Neil Fuller     * wildcard address. The backlog is set to 50. If {@code port == 0}, a port will be assigned by
707d5a8340b6f50d1d8677463897c3ba499fad3eb8Neil Fuller     * the OS.
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
72a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * @throws IOException if an error occurs while creating the socket.
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
74a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    public ServerSocket(int port) throws IOException {
7572ed50d1e9048b79efdb5b9e4ffb07c99a302d84Lorenzo Colitti        this(port, DEFAULT_BACKLOG, Inet6Address.ANY);
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
797d5a8340b6f50d1d8677463897c3ba499fad3eb8Neil Fuller     * Constructs a new {@code ServerSocket} instance bound to the given {@code port} using a
807d5a8340b6f50d1d8677463897c3ba499fad3eb8Neil Fuller     * wildcard address. The backlog is set to {@code backlog}.
81a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * If {@code port == 0}, a port will be assigned by the OS.
82f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
83a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * @throws IOException if an error occurs while creating the socket.
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
85a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    public ServerSocket(int port, int backlog) throws IOException {
8672ed50d1e9048b79efdb5b9e4ffb07c99a302d84Lorenzo Colitti        this(port, backlog, Inet6Address.ANY);
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
90a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * Constructs a new {@code ServerSocket} instance bound to the given {@code localAddress}
91a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * and {@code port}. The backlog is set to {@code backlog}.
92a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * If {@code localAddress == null}, the ANY address is used.
93a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * If {@code port == 0}, a port will be assigned by the OS.
94f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
95a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes     * @throws IOException if an error occurs while creating the socket.
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
97a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    public ServerSocket(int port, int backlog, InetAddress localAddress) throws IOException {
98a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        checkListen(port);
99a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        this.impl = factory != null ? factory.createSocketImpl()
100f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                : new PlainServerSocketImpl();
10172ed50d1e9048b79efdb5b9e4ffb07c99a302d84Lorenzo Colitti        InetAddress addr = (localAddress == null) ? Inet6Address.ANY : localAddress;
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.create(true);
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
106a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes                impl.bind(addr, port);
107933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller                readBackBindState();
108a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes                impl.listen(backlog > 0 ? backlog : DEFAULT_BACKLOG);
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                close();
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
117933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller     * Read the cached isBound and localAddress state from the underlying OS socket.
118933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller     */
119933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    private void readBackBindState() throws SocketException {
120933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        localAddress = IoBridge.getSocketLocalAddress(impl.fd);
121933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        isBound = true;
122933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    }
123933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller
124933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller    /**
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Waits for an incoming request and blocks until the connection is opened.
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method returns a socket object representing the just opened
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * connection.
128f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the connection representing socket.
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while accepting a new connection.
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket accept() throws IOException {
134a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        checkOpen();
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
136b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket is not bound");
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Socket aSocket = new Socket();
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
14155392539fea537abfb6581b474918f9d611fba27Jesse Wilson            implAccept(aSocket);
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            aSocket.close();
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw e;
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return aSocket;
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
149ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes    private void checkListen(int aPort) {
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (aPort < 0 || aPort > 65535) {
151b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("Port out of range: " + aPort);
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes this server socket and its implementation. Any attempt to connect
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to this socket thereafter will fail.
158f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing this socket.
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void close() throws IOException {
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isClosed = true;
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.close();
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
16847ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller     * Gets the local IP address of this server socket if this socket has ever been bound,
16947ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller     * {@code null} otherwise. This is useful for multihomed hosts.
170f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the local address of this server socket.
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InetAddress getInetAddress() {
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
177933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        return localAddress;
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
18147ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller     * Gets the local port of this server socket or {@code -1} if the socket is not bound.
18247ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller     * If the socket has ever been bound this method will return the local port it was bound to,
18347ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller     * even after it has been closed.
184f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the local port this server is listening on.
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getLocalPort() {
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getLocalPort();
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
19506f47d3e721e7032c97f80b3b2c7d25a8e6f2d21Brian Carlstrom     * Gets the socket {@link SocketOptions#SO_TIMEOUT accept timeout}.
196f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the option cannot be retrieved.
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getSoTimeout() throws IOException {
201a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        checkOpen();
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Integer) impl.getOption(SocketOptions.SO_TIMEOUT)).intValue();
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Invokes the server socket implementation to accept a connection on the
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * given socket {@code aSocket}.
208f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param aSocket
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the concrete {@code SocketImpl} to accept the connection
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            request on.
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the connection cannot be accepted.
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected final void implAccept(Socket aSocket) throws IOException {
21655392539fea537abfb6581b474918f9d611fba27Jesse Wilson        synchronized (this) {
21755392539fea537abfb6581b474918f9d611fba27Jesse Wilson            impl.accept(aSocket.impl);
21855392539fea537abfb6581b474918f9d611fba27Jesse Wilson            aSocket.accepted();
21955392539fea537abfb6581b474918f9d611fba27Jesse Wilson        }
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the server socket implementation factory of this instance. This
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * method may only be invoked with sufficient security privilege and only
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * once during the application lifetime.
226f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param aFactory
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the streaming socket factory to be used for further socket
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            instantiations.
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the factory could not be set or is already set.
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
233a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    public static synchronized void setSocketFactory(SocketImplFactory aFactory) throws IOException {
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (factory != null) {
235b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Factory already set");
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        factory = aFactory;
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
24106f47d3e721e7032c97f80b3b2c7d25a8e6f2d21Brian Carlstrom     * Sets the {@link SocketOptions#SO_TIMEOUT accept timeout} in milliseconds for this socket.
2424e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * This accept timeout defines the period the socket will block waiting to
2434e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * accept a connection before throwing an {@code InterruptedIOException}. The value
2444e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * {@code 0} (default) is used to set an infinite timeout. To have effect
2454e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * this option must be set before the blocking method was called.
246f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2474e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * @param timeout the timeout in milliseconds or 0 for no timeout.
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setSoTimeout(int timeout) throws SocketException {
252a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        checkOpen();
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timeout < 0) {
254b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("timeout < 0");
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a textual representation of this server socket including the
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address, port and the state. The port field is set to {@code 0} if there
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is no connection to the server socket.
263f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the textual socket representation.
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
268a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        StringBuilder result = new StringBuilder(64);
269f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        result.append("ServerSocket[");
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
271f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            return result.append("unbound]").toString();
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
273f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        return result.append("addr=")
274f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                .append(getInetAddress().getHostName()).append("/")
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .append(getInetAddress().getHostAddress()).append(
276f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        ",port=0,localport=")
277f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                .append(getLocalPort()).append("]")
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .toString();
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
2824d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * Binds this server socket to the given local socket address with a maximum
2834d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * backlog of 50 unaccepted connections. If the {@code localAddr} is set to
2844d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * {@code null} the socket will be bound to an available local address on
2854d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * any free port of the system.
286f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddr
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the local address and port to bind on.
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the {@code SocketAddress} is not supported.
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already bound or a problem occurs during
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             binding.
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void bind(SocketAddress localAddr) throws IOException {
296a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        bind(localAddr, DEFAULT_BACKLOG);
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Binds this server socket to the given local socket address. If the
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code localAddr} is set to {@code null} the socket will be bound to an
3024d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * available local address on any free port of the system.
303f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
3044d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * @param localAddr the local machine address and port to bind on.
3054d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * @param backlog the maximum number of unaccepted connections. Passing 0 or
3064d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     *     a negative value yields the default backlog of 50.
3074d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * @throws IllegalArgumentException if the {@code SocketAddress} is not
3084d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     *     supported.
3094d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * @throws IOException if the socket is already bound or a problem occurs
3104d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     *     during binding.
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void bind(SocketAddress localAddr, int backlog) throws IOException {
313a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        checkOpen();
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isBound()) {
315b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new BindException("Socket is already bound");
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
317933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        InetAddress addr;
318933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        int port;
319933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        if (localAddr == null) {
32072ed50d1e9048b79efdb5b9e4ffb07c99a302d84Lorenzo Colitti            addr = Inet6Address.ANY;
321933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller            port = 0;
322933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        } else {
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!(localAddr instanceof InetSocketAddress)) {
324b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new IllegalArgumentException("Local address not an InetSocketAddress: " +
325b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                        localAddr.getClass());
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetSocketAddress inetAddr = (InetSocketAddress) localAddr;
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((addr = inetAddr.getAddress()) == null) {
329b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new SocketException("Host is unresolved: " + inetAddr.getHostName());
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            port = inetAddr.getPort();
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.bind(addr, port);
337933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller                readBackBindState();
338a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes                impl.listen(backlog > 0 ? backlog : DEFAULT_BACKLOG);
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                close();
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
34747ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller     * Gets the local socket address of this server socket or {@code null} if the socket is unbound.
34847ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller     * This is useful on multihomed hosts. If the socket has ever been bound this method will return
34947ae0b5a1d96c8030e0963ccc5b44c3ee66aaec3Neil Fuller     * the local address it was bound to, even after it has been closed.
350f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the local socket address and port this socket is bound to.
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketAddress getLocalSocketAddress() {
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
357933fbbf606268eec9fc430632b8bca7002a833b3Neil Fuller        return new InetSocketAddress(localAddress, getLocalPort());
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this server socket is bound to a local address and port
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * or not.
363f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this socket is bound, {@code false} otherwise.
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isBound() {
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isBound;
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this server socket is closed or not.
372f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this socket is closed, {@code false} otherwise.
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isClosed() {
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isClosed;
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
379a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    private void checkOpen() throws SocketException {
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isClosed()) {
381b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket is closed");
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the value for the socket option {@code SocketOptions.SO_REUSEADDR}.
387f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param reuse
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the socket option setting.
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option value.
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setReuseAddress(boolean reuse) throws SocketException {
394a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        checkOpen();
3950371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(reuse));
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the socket option {@code SocketOptions.SO_REUSEADDR}.
400f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the option is enabled, {@code false} otherwise.
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the option value.
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getReuseAddress() throws SocketException {
406a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        checkOpen();
407a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        return ((Boolean) impl.getOption(SocketOptions.SO_REUSEADDR)).booleanValue();
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
411a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes     * Sets this socket's {@link SocketOptions#SO_SNDBUF receive buffer size}.
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setReceiveBufferSize(int size) throws SocketException {
414a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        checkOpen();
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (size < 1) {
416b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("size < 1");
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
422a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes     * Returns this socket's {@link SocketOptions#SO_RCVBUF receive buffer size}.
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getReceiveBufferSize() throws SocketException {
425a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes        checkOpen();
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Integer) impl.getOption(SocketOptions.SO_RCVBUF)).intValue();
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4300d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * Returns this socket's {@code ServerSocketChannel}, if one exists. A channel is
4310d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * available only if this socket wraps a channel. (That is, you can go from a
4320d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * channel to a socket and back again, but you can't go from an arbitrary socket to a channel.)
4330d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * In practice, this means that the socket must have been created by
4340d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * {@link java.nio.channels.ServerSocketChannel#open}.
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ServerSocketChannel getChannel() {
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets performance preferences for connection time, latency and bandwidth.
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method does currently nothing.
444f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param connectionTime
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of a short connecting
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            time.
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param latency
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of low latency.
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bandwidth
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of high bandwidth.
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
453a3b57e9cb41fb00ac607cd330fa73270b564b66cElliott Hughes    public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Our socket implementation only provide one protocol: TCP/IP, so
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // we do nothing for this method
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
458