web-dev-qa-db-fra.com

Limite de connexion Java ServerSocket?

J'exécutais quelques tests avec des sockets, et j'ai rencontré un comportement étrange: Un ServerSocket refusera les connexions après que le 50ème Socket client se soit connecté, même si ce socket client est fermé avant que le suivant ne soit ouvert, et même si un délai est écoulé. ajouté entre les connexions.

Le programme suivant est mon code expérimental qui, dans son état actuel, ne déclenche aucune exception et se termine normalement. Toutefois, si la taille de la matrice Socket[] clients est augmentée au-delà de 50, tous les sockets client tentant de se connecter après la 50e connexion sont refusés par la socket du serveur.

Question: Pourquoi 50 correspond-il au nombre de connexions de socket refusées par un socket de serveur?

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();
    }
}

J'ai exécuté des tests où 50 autres sockets se connectent à un autre serveur local, et aucun problème ne s'est produit lors de l'ouverture et de la fermeture de 100 sockets. J'ai donc déduit que c'est le socket du serveur qui refuse les connexions, et non une limite d'ouverture des sockets client. Je n'ai pas pu comprendre pourquoi le socket du serveur est limité à 50 connexions, même si elles ne sont pas connectées simultanément.

11
Vulcan

Tout est dans le JavaDoc :

La longueur maximale de la file d'attente pour les indications de connexion entrantes (demande de connexion) est définie sur 50. Si une indication de connexion arrive lorsque la file d'attente est saturée, la connexion est refusée.

Apparemment, votre ServerSocket n'accepte jamais de connexion, écoute seulement. Vous devez appeler accept() et commencer à gérer la connexion ou augmenter la taille de la file d'attente backlog:

new ServerSocket(port, 100)
14
Tomasz Nurkiewicz

50 est la valeur par défaut pour backlog

http://docs.Oracle.com/javase/1.4.2/docs/api/Java/net/ServerSocket.html#ServerSocket%28int%29

La longueur maximale de la file d'attente pour les indications de connexion entrantes (demande de connexion) est définie sur 50. Si une indication de connexion arrive lorsque la file d'attente est saturée, la connexion est refusée.

4
irreputable

Voici un exemple qui fonctionne, conformément à la réponse 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);
    }

  }
}
2
GreyBeardedGeek

Deux choses que vous pouvez regarder

  1. Le serveur n'accepte pas la connexion.
  2. Le serveur ne peut pas gérer trop de connexions en même temps. Cela pourrait être dû à un arriéré accru (au-delà de 50). Essayez de laisser un intervalle de temps en millisecondes avant de vous reconnecter au serveur. Comme des connexions de montée en puissance. Je l'ai résolu en donnant un peu de temps quand j'ai couru la charge de test.
0
Jiten