2010-03-14 14 views
5

Da quello che ho letto su Java NIO e SocketChannels [Server] non bloccanti, dovrebbe essere possibile scrivere un server TCP che supporta diverse connessioni usando un solo thread - Io farei un Selettore che aspetta tutti i canali rilevanti nel loop del server.Socket Java: posso scrivere un server TCP con un thread?

È giusto o mi mancano alcuni dettagli importanti? Quali problemi posso incontrare?

(Sfondo:.. La comunicazione TCP sarebbe per un piccolo gioco multiplayer, in modo da max 10-20 connessioni simultanee I messaggi saranno inviati circa ogni pochi secondi.)

risposta

2

Sì, hai ragione. I problemi che puoi incontrare sono quando la durata dell'elaborazione è troppo lunga. In questo caso, è necessario avvolgere l'elaborazione in un altro thread, in modo che non interferisca con il thread di rete e prevenga ritardi evidenti.

Un altro dettaglio; I canali riguardano i dati "in movimento". Se i dati che desideri inviare sono pronti, puoi spostare questi dati su un canale di rete. La copia/buffering/ecc. è tutto fatto dall'implementazione NIO, quindi.
Il "thread di rete" a thread singolo sta solo guidando la connessione, ma non la limita (leggi: strana analogia con una macchina).

L'approccio multithread di base è più semplice da progettare e implementare rispetto a un NIO a thread singolo. Il guadagno di prestazioni non è evidente in un piccolo server/client di gioco multiplayer, specialmente se un messaggio viene inviato solo ogni pochi secondi.

+0

Bene ... sembra molto familiare per oscillare la programmazione .. dove si dispone di un thread di invio evento principale, ma nel caso del server, il nome è "Request Dispatch Thread". E c'è anche la buona pratica di delegare ad altri thread quegli eventi/requisiti che richiedono un po 'di elaborazione che potrebbe richiedere più di un secondo per liberare il thread di polling. Ha senso ragazzi o sto solo dicendo matto? – Victor

+1

Sì, quello che dici ha un senso. Quello che descrivi è tipico per i processori di eventi. La richiesta viene gestita come un evento e il canale su cui i dati diventano disponibili o verranno scritti viene gestito da un thread diverso rispetto all'accettore. Si noti che con il modello di I/O originale si presuppone spesso che un server generi un nuovo thread per client, ma questo modello basato su eventi con un numero fisso di thread è ugualmente utile. – Pindatjuh

0

Sì, è possibile. Vedere this example per un'illustrazione su come eseguire questa operazione.

La sezione importante è questa:

for (;;) { // Loop forever, processing client connections 
    // Wait for a client to connect 
    SocketChannel client = server.accept(); 

    // Build response string, wrap, and encode to bytes (elided) 

    client.write(response); 
    client.close(); 
} 

Tutto questo funziona bene quando l'elaborazione lato server per ogni cliente è trascurabile. Tuttavia, un approccio a più thread si ridimensionerà molto meglio.

2

Brian Agnew ha dichiarato:

Questo tutto funziona bene quando l'elaborazione lato server per ogni cliente è trascurabile. Tuttavia, un approccio multi-thread si ridimensionerà molto meglio.

Mi permetto di non essere d'accordo. Un approccio one-client-one-thread esaurirà la memoria molto più rapidamente rispetto a se gestisci più client per thread, poiché non avrai bisogno di uno stack completo per client. Vedere la carta C10K per ulteriori informazioni sull'argomento: http://www.kegel.com/c10k.html

In ogni caso, se non ci saranno più di 20 client, basta usare qualunque cosa sia più facile da codificare e eseguire il debug.

Problemi correlati