}
/**
- * Binds this server socket to the given local socket address. The default
- * number of pending connections may be backlogged. If the {@code localAddr}
- * is set to {@code null} the socket will be bound to an available local
- * address on any free port of the system.
+ * Binds this server socket to the given local socket address with a maximum
+ * backlog of 50 unaccepted connections. If the {@code localAddr} is set to
+ * {@code null} the socket will be bound to an available local address on
+ * any free port of the system.
*
* @param localAddr
* the local address and port to bind on.
/**
* Binds this server socket to the given local socket address. If the
* {@code localAddr} is set to {@code null} the socket will be bound to an
- * available local address on any free port of the system. The value for
- * {@code backlog} must e greater than {@code 0} otherwise the default value
- * will be used.
+ * available local address on any free port of the system.
*
- * @param localAddr
- * the local machine address and port to bind on.
- * @param backlog
- * the number of pending connection requests, before requests
- * will be rejected.
- * @throws IllegalArgumentException
- * if the {@code SocketAddress} is not supported.
- * @throws IOException
- * if the socket is already bound or a problem occurs during
- * binding.
+ * @param localAddr the local machine address and port to bind on.
+ * @param backlog the maximum number of unaccepted connections. Passing 0 or
+ * a negative value yields the default backlog of 50.
+ * @throws IllegalArgumentException if the {@code SocketAddress} is not
+ * supported.
+ * @throws IOException if the socket is already bound or a problem occurs
+ * during binding.
*/
public void bind(SocketAddress localAddr, int backlog) throws IOException {
checkClosedAndCreate(true);
}
/**
- * Creates a new server socket which is bound to the given port.
+ * Creates a new server socket which is bound to the given port with a
+ * maximum backlog of 50 unaccepted connections.
*
- * @param port
- * the port on which the created socket has to listen.
+ * @param port the port on which the created socket has to listen.
* @return the created bound server socket.
* @throws IOException
* if an error occurs while creating a new server socket.
* Creates a new server socket which is bound to the given port and
* configures its maximum of queued connections.
*
- * @param port
- * the port on which the created socket has to listen.
- * @param backlog
- * the maximum of queued connections.
+ * @param port the port on which the created socket has to listen.
+ * @param backlog the maximum number of unaccepted connections. Passing 0 or
+ * a negative value yields the default backlog of 50.
* @return the created bound server socket.
- * @throws IOException
- * if an error occurs while creating a new server socket.
+ * @throws IOException if an error occurs while creating a new server socket.
*/
public abstract ServerSocket createServerSocket(int port, int backlog) throws IOException;
* Creates a new server socket which is bound to the given address on the
* specified port and configures its maximum of queued connections.
*
- * @param port
- * the port on which the created socket has to listen.
- * @param backlog
- * the maximum of queued connections.
- * @param iAddress
- * the address of the network interface which is used by the
- * created socket.
+ * @param port the port on which the created socket has to listen.
+ * @param backlog the maximum number of unaccepted connections. Passing 0 or
+ * a negative value yields the default backlog of 50.
+ * @param iAddress the address of the network interface which is used by the
+ * created socket.
* @return the created bound server socket.
- * @throws IOException
- * if an error occurs while creating a new server socket.
+ * @throws IOException if an error occurs while creating a new server socket.
*/
public abstract ServerSocket createServerSocket(int port, int backlog, InetAddress iAddress)
throws IOException;
--- /dev/null
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ServerSocketFactory;
+import junit.framework.TestCase;
+
+public class ServerSocketFactoryTest extends TestCase {
+
+ public void testCreateServerSocket() throws IOException {
+ ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket();
+ serverSocket.bind(new InetSocketAddress(0));
+ testSocket(serverSocket, 50);
+ }
+
+ public void testCreateServerSocketWithPort() throws IOException {
+ ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(0);
+ testSocket(serverSocket, 50);
+ }
+
+ public void testCreateServerSocketWithPortNoBacklog() throws IOException {
+ ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(0, 1);
+ testSocket(serverSocket, 1);
+ }
+
+ public void testCreateServerSocketWithPortZeroBacklog() throws IOException {
+ ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(0, 0);
+ testSocket(serverSocket, 50);
+ }
+
+ public void testCreateServerSocketWithPortAndBacklog() throws IOException {
+ ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(0, 50);
+ testSocket(serverSocket, 50);
+ }
+
+ private void testSocket(final ServerSocket serverSocket, int specifiedBacklog)
+ throws IOException {
+ final byte[] data = "abc".getBytes();
+
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ Socket s = serverSocket.accept();
+ s.getOutputStream().write(data);
+ s.close();
+ } catch (IOException e) {
+ }
+ }
+ }).start();
+
+ Socket socket = new Socket(InetAddress.getLocalHost(), serverSocket.getLocalPort());
+ assertBacklog(specifiedBacklog, new InetSocketAddress(
+ InetAddress.getLocalHost(), serverSocket.getLocalPort()));
+
+ InputStream in = socket.getInputStream();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ transfer(in, out);
+ assertEquals(Arrays.toString(data), Arrays.toString(out.toByteArray()));
+ socket.close();
+
+ serverSocket.close();
+ }
+
+ /**
+ * Validates that the backlog of the listening address is as specified.
+ */
+ private void assertBacklog(int specifiedBacklog, InetSocketAddress serverAddress)
+ throws IOException {
+ List<Socket> backlog = new ArrayList<Socket>();
+ int peak = 0;
+ try {
+ int max = 100;
+ for (int i = 0; i < max; i++) {
+ Socket socket = new Socket();
+ backlog.add(socket);
+ socket.connect(serverAddress, 500);
+ peak++;
+ }
+ fail("Failed to exhaust backlog after " + max + " connections!");
+ } catch (IOException expected) {
+ }
+
+ System.out.println("backlog peaked at " + peak);
+
+ for (Socket socket : backlog) {
+ socket.close();
+ }
+
+ /*
+ * In 4.5 of UNIX Network Programming, Stevens says:
+ * "Berkeley-derived implementations add a fudge factor to the
+ * backlog: it is multiplied by 1.5."
+ *
+ * We've observed that Linux always adds 3 to the user-specified
+ * backlog.
+ */
+ assertTrue(peak >= specifiedBacklog && peak <= (specifiedBacklog + 3) * 1.5);
+ }
+
+ private void transfer(InputStream in, ByteArrayOutputStream out) throws IOException {
+ byte[] buffer = new byte[1024];
+ int count;
+ while ((count = in.read(buffer)) != -1) {
+ out.write(buffer, 0, count);
+ }
+ }
+}