example - Límite de conexión Java ServerSocket?
spring security oauth2 (3)
Estaba ejecutando algunas pruebas con sockets y encontré un comportamiento extraño: Un ServerSocket rechazará las conexiones después de que el cliente número 50 se conecte a él, incluso si ese socket de cliente se cierra antes de que se abra el siguiente, e incluso si se produce un retraso agregado entre las conexiones.
El siguiente programa es mi código experimental, que en su estado actual no arroja excepciones y finaliza normalmente. Sin embargo, si el tamaño de la matriz de los Socket[] clients
de Socket[] clients
se incrementa más allá de 50, el socket del servidor rechazará los sockets de los clientes que intenten conectarse después de la conexión número 50.
Pregunta: ¿Por qué 50 es el recuento en el que las conexiones de socket son rechazadas por un socket de servidor?
public static void main(String[] args) {
try (ServerSocket server = new ServerSocket(2123)) {
Socket[] clients = new Socket[50];
for (int i = 0; i < clients.length; i++) {
clients[i] = new Socket("localhost", 2123);
System.out.printf("Client %2d: " + clients[i] + "%n", i);
clients[i].close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
He realizado pruebas donde otros 50 sockets se conectan a otro servidor local, y no ocurrió ningún problema con 100 sockets abiertos y cerrados, por lo que deduje que es el socket del servidor el que rechaza las conexiones, y no un límite de apertura de sockets de clientes, pero No he podido descubrir por qué el socket del servidor está limitado a 50 conexiones, aunque no estén conectadas simultáneamente.
50 es el valor predeterminado para la backlog
http://docs.oracle.com/javase/1.4.2/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29
La longitud máxima de la cola para las indicaciones de conexión entrante (una solicitud de conexión) se establece en 50. Si llega una indicación de conexión cuando la cola está llena, la conexión se rechaza.
Aquí hay un ejemplo que funciona, de acuerdo con la respuesta de @TomaszNurkiewicz:
import java.net.*;
import java.util.concurrent.atomic.AtomicBoolean;
public class SockTest{
public static void main(String[] args) {
final AtomicBoolean shouldRun = new AtomicBoolean(true);
try {
final ServerSocket server = new ServerSocket(2123);
Thread serverThread = new Thread(){
public void run() {
try {
while(shouldRun.get()) {
Socket s = server.accept();
s.close();
Thread.sleep(1);
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
};
serverThread.start();
Socket[] clients = new Socket[150];
for (int i = 0; i < clients.length; i++) {
clients[i] = new Socket("localhost", 2123);
System.out.printf("Client %2d: " + clients[i] + "%n", i);
clients[i].close();
}
shouldRun.set(false);
} catch (Exception e) {
e.printStackTrace();
} finally {
shouldRun.set(false);
}
}
}
Todo está en JavaDoc :
La longitud máxima de la cola para las indicaciones de conexión entrante (una solicitud de conexión) se establece en 50. Si llega una indicación de conexión cuando la cola está llena, la conexión se rechaza.
Aparentemente su ServerSocket
nunca acepta ninguna conexión, solo escucha. Debe llamar a accept()
y comenzar a manejar la conexión o aumentar el tamaño de la cola de espera :
new ServerSocket(port, 100)