2012-10-19 14 views
10

Stavo eseguendo alcuni test con i socket e ho riscontrato un comportamento strano: un ServerSocket rifiuterà le connessioni dopo che il 50th client Socket si è connesso ad esso, anche se quel socket client è stato chiuso prima che il successivo sia aperto, e anche se un il ritardo viene aggiunto tra le connessioni.Limite di connessione Java ServerSocket?

Il seguente programma è il mio codice sperimentale, che nel suo stato attuale non emette eccezioni e termina normalmente. Tuttavia, se la dimensione dell'array di Socket[] clients viene aumentata oltre 50, tutti i socket client che tentano di connettersi dopo la 50ª connessione vengono rifiutati dal socket del server.

Domanda: Perché 50 è il conteggio con cui le connessioni socket vengono rifiutate da un socket del server?

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

Ho eseguito test dove altri 50 prese connettono a un altro server locale, e nessun problema si è verificato con 100 prese vengono aperte e chiuse, così ho dedotto che la sua presa server rifiuta connessioni, e non alcuni limiti di apertura dei socket client, ma non sono stato in grado di scoprire perché il socket del server è limitato a 50 connessioni, anche se non sono connesse simultaneamente.

risposta

12

È tutto nel JavaDoc:

La lunghezza della coda massima per le indicazioni di connessione in entrata (a richiesta di connessione) è impostato su 50. Se un'indicazione collegamento arriva quando la coda è piena, il collegamento è rifiutato

Apparentemente il tuo ServerSocket non accetta mai alcuna connessione, ascolta solo. È necessario sia chiamare accept() e iniziare a gestire la connessione o aumentare la coda backlog dimensioni:

new ServerSocket(port, 100) 
+2

Le connessioni in coda non verrebbero rimosse quando i socket client sono chiusi? – Vulcan

+1

@Vulcan Chiaramente no. – EJP

+1

@EJP Sì, ma perché non dovrebbero?A me sembra strano che le prese chiuse rimangano in attesa di connessione. Immagino che non ci sia modo per il socket del server di sapere che il socket client è chiuso. – Vulcan

2

Ecco un esempio che funziona, in accordo con @ di TomaszNurkiewicz risposta:

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

    } 
} 
+0

Grazie; In realtà ho creato un esempio simile dopo aver visto la risposta di @ TomaszNurkiewicz in precedenza, ma non così pulita come la tua (ho dimenticato AtomicBoolean e reso la mia classe improvvisata con la stessa funzionalità haha). +1 – Vulcan

0

Due cose che si possono guarda

  1. Il server non accetta la connessione.
  2. Il server non è in grado di gestire troppe connessioni contemporaneamente. Potrebbe essere causato da un aumento degli arretrati (oltre 50). Prova a dare un po 'di tempo in milli secondi prima di connetterti nuovamente al server. Come ramp up connessioni. Ho risolto il problema dando un po 'di tempo quando ho eseguito il carico di prova.
Problemi correlati