ServerSocket.java revision a9c6c9013b08934867f71b69a90efce0c1b66918
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
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.ServerSocketChannel;
22f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport org.apache.harmony.luni.net.PlainServerSocketImpl;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class represents a server-side socket that waits for incoming client
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connections. A {@code ServerSocket} handles the requests and sends back an
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * appropriate reply. The actual tasks that a server socket must accomplish are
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implemented by an internal {@code SocketImpl} instance.
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class ServerSocket {
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    SocketImpl impl;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static SocketImplFactory factory;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private volatile boolean isCreated;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isBound;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isClosed;
41f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code ServerSocket} instance which is not bound to any
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * port. The default number of pending connections may be backlogged.
45f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the server socket.
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ServerSocket() throws IOException {
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl = factory != null ? factory.createSocketImpl()
51f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                : new PlainServerSocketImpl();
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
55f1072c37db1f647ab6bbbb9b866b699ef1e19ec3Elliott Hughes     * Unspecified constructor needed by ServerSocketChannelImpl.ServerSocketAdapter.
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @hide
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected ServerSocket(SocketImpl impl) {
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.impl = impl;
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code ServerSocket} instance bound to the nominated
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * port on the localhost. The default number of pending connections may be
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * backlogged. If {@code aport} is 0 a free port is assigned to the socket.
67f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param aport
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port number to listen for connection requests on.
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the server socket.
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ServerSocket(int aport) throws IOException {
74051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        this(aport, defaultBacklog(), Inet4Address.ANY);
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code ServerSocket} instance bound to the nominated
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * port on the localhost. The number of pending connections that may be
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * backlogged is specified by {@code backlog}. If {@code aport} is 0 a free
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * port is assigned to the socket.
82f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param aport
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port number to listen for connection requests on.
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param backlog
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of pending connection requests, before requests
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            will be rejected.
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the server socket.
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ServerSocket(int aport, int backlog) throws IOException {
92051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        this(aport, backlog, Inet4Address.ANY);
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new {@code ServerSocket} instance bound to the nominated
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * local host address and port. The number of pending connections that may
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * be backlogged is specified by {@code backlog}. If {@code aport} is 0 a
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * free port is assigned to the socket.
100f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param aport
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port number to listen for connection requests on.
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddr
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the local machine address to bind on.
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param backlog
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of pending connection requests, before requests
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            will be rejected.
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the server socket.
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ServerSocket(int aport, int backlog, InetAddress localAddr)
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super();
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkListen(aport);
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl = factory != null ? factory.createSocketImpl()
116f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                : new PlainServerSocketImpl();
117051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        InetAddress addr = localAddr == null ? Inet4Address.ANY : localAddr;
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.create(true);
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isCreated = true;
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.bind(addr, aport);
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isBound = true;
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.listen(backlog > 0 ? backlog : defaultBacklog());
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                close();
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Waits for an incoming request and blocks until the connection is opened.
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method returns a socket object representing the just opened
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * connection.
137f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the connection representing socket.
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while accepting a new connection.
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket accept() throws IOException {
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(false);
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
145b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket is not bound");
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Socket aSocket = new Socket();
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
15055392539fea537abfb6581b474918f9d611fba27Jesse Wilson            implAccept(aSocket);
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (SecurityException e) {
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            aSocket.close();
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw e;
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            aSocket.close();
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw e;
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return aSocket;
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks whether the server may listen for connection requests on {@code
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * aport}. Throws an exception if the port is outside the valid range
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code 0 <= aport <= 65535 }or does not satisfy the security policy.
165f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param aPort
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the candidate port to listen on.
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void checkListen(int aPort) {
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (aPort < 0 || aPort > 65535) {
171b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("Port out of range: " + aPort);
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (security != null) {
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            security.checkListen(aPort);
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes this server socket and its implementation. Any attempt to connect
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to this socket thereafter will fail.
182f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing this socket.
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void close() throws IOException {
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isClosed = true;
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.close();
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1923bf03b8be207d0c760bcad5eae5028e854498376Elliott Hughes     * Returns the default number of pending connections on a server socket. If
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the backlog value maximum is reached, any subsequent incoming request is
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * rejected.
195f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return int the default number of pending connection requests
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static int defaultBacklog() {
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return 50;
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the local IP address of this server socket or {@code null} if the
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * socket is unbound. This is useful for multihomed hosts.
205f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the local address of this server socket.
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InetAddress getInetAddress() {
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getInetAddress();
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the local port of this server socket or {@code -1} if the socket is
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * unbound.
218f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the local port this server is listening on.
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getLocalPort() {
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getLocalPort();
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
22906f47d3e721e7032c97f80b3b2c7d25a8e6f2d21Brian Carlstrom     * Gets the socket {@link SocketOptions#SO_TIMEOUT accept timeout}.
230f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the option cannot be retrieved.
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getSoTimeout() throws IOException {
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isCreated) {
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            synchronized (this) {
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!isCreated) {
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    try {
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        impl.create(true);
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    } catch (SocketException e) {
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw e;
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    } catch (IOException e) {
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        throw new SocketException(e.toString());
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    isCreated = true;
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Integer) impl.getOption(SocketOptions.SO_TIMEOUT)).intValue();
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Invokes the server socket implementation to accept a connection on the
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * given socket {@code aSocket}.
255f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param aSocket
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the concrete {@code SocketImpl} to accept the connection
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            request on.
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the connection cannot be accepted.
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected final void implAccept(Socket aSocket) throws IOException {
26355392539fea537abfb6581b474918f9d611fba27Jesse Wilson        synchronized (this) {
26455392539fea537abfb6581b474918f9d611fba27Jesse Wilson            impl.accept(aSocket.impl);
26555392539fea537abfb6581b474918f9d611fba27Jesse Wilson            aSocket.accepted();
26655392539fea537abfb6581b474918f9d611fba27Jesse Wilson        }
26755392539fea537abfb6581b474918f9d611fba27Jesse Wilson        SecurityManager security = System.getSecurityManager();
26855392539fea537abfb6581b474918f9d611fba27Jesse Wilson        if (security != null) {
26955392539fea537abfb6581b474918f9d611fba27Jesse Wilson            security.checkAccept(aSocket.getInetAddress().getHostAddress(),
27055392539fea537abfb6581b474918f9d611fba27Jesse Wilson                    aSocket.getPort());
27155392539fea537abfb6581b474918f9d611fba27Jesse Wilson        }
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the server socket implementation factory of this instance. This
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * method may only be invoked with sufficient security privilege and only
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * once during the application lifetime.
278f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param aFactory
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the streaming socket factory to be used for further socket
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            instantiations.
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the factory could not be set or is already set.
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static synchronized void setSocketFactory(SocketImplFactory aFactory)
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (security != null) {
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            security.checkSetFactory();
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (factory != null) {
292b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Factory already set");
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        factory = aFactory;
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
29806f47d3e721e7032c97f80b3b2c7d25a8e6f2d21Brian Carlstrom     * Sets the {@link SocketOptions#SO_TIMEOUT accept timeout} in milliseconds for this socket.
2994e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * This accept timeout defines the period the socket will block waiting to
3004e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * accept a connection before throwing an {@code InterruptedIOException}. The value
3014e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * {@code 0} (default) is used to set an infinite timeout. To have effect
3024e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * this option must be set before the blocking method was called.
303f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
3044e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * @param timeout the timeout in milliseconds or 0 for no timeout.
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setSoTimeout(int timeout) throws SocketException {
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timeout < 0) {
311b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("timeout < 0");
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a textual representation of this server socket including the
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * address, port and the state. The port field is set to {@code 0} if there
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is no connection to the server socket.
320f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the textual socket representation.
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
325a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson        StringBuilder result = new StringBuilder(64);
326f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        result.append("ServerSocket[");
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
328f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            return result.append("unbound]").toString();
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
330f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        return result.append("addr=")
331f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                .append(getInetAddress().getHostName()).append("/")
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .append(getInetAddress().getHostAddress()).append(
333f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        ",port=0,localport=")
334f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                .append(getLocalPort()).append("]")
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .toString();
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3394d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * Binds this server socket to the given local socket address with a maximum
3404d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * backlog of 50 unaccepted connections. If the {@code localAddr} is set to
3414d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * {@code null} the socket will be bound to an available local address on
3424d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * any free port of the system.
343f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddr
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the local address and port to bind on.
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the {@code SocketAddress} is not supported.
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already bound or a problem occurs during
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             binding.
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void bind(SocketAddress localAddr) throws IOException {
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        bind(localAddr, defaultBacklog());
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Binds this server socket to the given local socket address. If the
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code localAddr} is set to {@code null} the socket will be bound to an
3594d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * available local address on any free port of the system.
360f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
3614d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * @param localAddr the local machine address and port to bind on.
3624d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * @param backlog the maximum number of unaccepted connections. Passing 0 or
3634d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     *     a negative value yields the default backlog of 50.
3644d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * @throws IllegalArgumentException if the {@code SocketAddress} is not
3654d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     *     supported.
3664d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     * @throws IOException if the socket is already bound or a problem occurs
3674d743816cad738bfeccf6dc210fc7c9bd84a8777Jesse Wilson     *     during binding.
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void bind(SocketAddress localAddr, int backlog) throws IOException {
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isBound()) {
372b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new BindException("Socket is already bound");
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int port = 0;
375051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        InetAddress addr = Inet4Address.ANY;
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (localAddr != null) {
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!(localAddr instanceof InetSocketAddress)) {
378b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new IllegalArgumentException("Local address not an InetSocketAddress: " +
379b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                        localAddr.getClass());
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetSocketAddress inetAddr = (InetSocketAddress) localAddr;
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((addr = inetAddr.getAddress()) == null) {
383b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new SocketException("Host is unresolved: " + inetAddr.getHostName());
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            port = inetAddr.getPort();
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (security != null) {
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            security.checkListen(port);
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.bind(addr, port);
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isBound = true;
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.listen(backlog > 0 ? backlog : defaultBacklog());
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                close();
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the local socket address of this server socket or {@code null} if
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the socket is unbound. This is useful on multihomed hosts.
407f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the local socket address and port this socket is bound to.
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketAddress getLocalSocketAddress() {
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new InetSocketAddress(getInetAddress(), getLocalPort());
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this server socket is bound to a local address and port
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * or not.
420f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this socket is bound, {@code false} otherwise.
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isBound() {
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isBound;
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this server socket is closed or not.
429f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this socket is closed, {@code false} otherwise.
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isClosed() {
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isClosed;
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks whether the socket is closed, and throws an exception.
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void checkClosedAndCreate(boolean create) throws SocketException {
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isClosed()) {
441b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket is closed");
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!create || isCreated) {
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (isCreated) {
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.create(true);
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (SocketException e) {
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new SocketException(e.toString());
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isCreated = true;
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the value for the socket option {@code SocketOptions.SO_REUSEADDR}.
465f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param reuse
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the socket option setting.
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option value.
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setReuseAddress(boolean reuse) throws SocketException {
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
4730371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(reuse));
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the value of the socket option {@code SocketOptions.SO_REUSEADDR}.
478f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the option is enabled, {@code false} otherwise.
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the option value.
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getReuseAddress() throws SocketException {
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Boolean) impl.getOption(SocketOptions.SO_REUSEADDR))
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                .booleanValue();
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
490a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes     * Sets this socket's {@link SocketOptions#SO_SNDBUF receive buffer size}.
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setReceiveBufferSize(int size) throws SocketException {
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (size < 1) {
495b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("size < 1");
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
501a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes     * Returns this socket's {@link SocketOptions#SO_RCVBUF receive buffer size}.
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getReceiveBufferSize() throws SocketException {
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkClosedAndCreate(true);
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return ((Integer) impl.getOption(SocketOptions.SO_RCVBUF)).intValue();
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
5090d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * Returns this socket's {@code ServerSocketChannel}, if one exists. A channel is
5100d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * available only if this socket wraps a channel. (That is, you can go from a
5110d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * channel to a socket and back again, but you can't go from an arbitrary socket to a channel.)
5120d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * In practice, this means that the socket must have been created by
5130d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * {@link java.nio.channels.ServerSocketChannel#open}.
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ServerSocketChannel getChannel() {
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets performance preferences for connection time, latency and bandwidth.
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method does currently nothing.
523f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param connectionTime
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of a short connecting
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            time.
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param latency
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of low latency.
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bandwidth
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of high bandwidth.
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setPerformancePreferences(int connectionTime, int latency,
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int bandwidth) {
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Our socket implementation only provide one protocol: TCP/IP, so
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // we do nothing for this method
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
538