Newsgroup: it.comp.java
Titolo: domandina banale per gli esperti di socket

Una domanda che gli esperti di connessioni via socket (purtroppo io non lo sono) troveranno banale: ho scritto un piccolo server telnet che ascolta su una certa porta . I client che si collegano via telnet possono inviare dei comandi per modificare lo stato dell'applicazione. Il codice, riassunto all'essenziale, e` :
boolean runDaemon = true
while (runDaemon) {
  Socket  clientSock        = serverSock.accept();
  boolean acceptClientInput = true ;
  InputStream is  = clientSock.getInputStream();
  InputStreamReader isr = new InputStreamReader(is);
  BufferedReader br = new BufferedReader(isr);
  OutputStream os = clientSock.getOutputStream();
  OutputStreamWriter osw = new OutputStreamWriter(os);
  BufferedWriter bw = new BufferedWriter(osw) ;
  // invia al client un messaggio di benvenuto
  bw.write("Benvenuto, ecc.") :
  bw.flush();
  while (acceptClientInput) {
 
    // mostra il prompt e aspetta il comando
 
    bw.write("> ");
    bw.flush();
    String clientCommand = br.readLine().trim().toUpperCase();
    // fa una serie di cose in base a clientCommand. Se il client da il
    // comando "QUIT" pone acceptClientInput = false
 
  }
  bw.close();
  osw.close();
  os.close(); 
  br.close();  
  isr.close();
  is.close();
  clientSock.close() ;
}
serverSock.close() ;
L'applicazione funziona con il primo client, ma se un secondo client cerca di entrare  non gli appare il messaggio di benvenuto e il prompt dei comandi anche se il client telnet da il messaggio "Connected to <host>".
La mia domandina e`: che cosa devo cambiare nel mio codice affinche` il server accetti piu` connessioni contemporaneamente?
Ciao e grazie per l'attenzione, Cristian
-- 
Cristian Veronesi - computer programmer
C.R.P.A. spa - Centro Ricerche Produzioni Animali / Research Centre for Animal Production 
Reggio Emilia, Italy

Ciao!
Lungi da me dichiararmi una esperta di socket! Probabilmente non ne ho mai
implementato uno direttamente.... pero' sono una brava bambina che studia
 ;) ] e ricordavo di aver visto sul mio manuale on line un esempio che fa al
caso tuo. Cosi' sono andata a recuperarlo e te lo pasto e posto per intero.
Da quello che ho capito si poggia sui thread. Sono due classi: una e'
l'applicazione vera e propria (la seconda)  e l'altra e' il thread che viene
chiamato dal main dell'applicazione che le demanda la comunicazione col
client. Cosi' il main rimane sempre in ascolto. Spero che tu abbia
dimestichezza con  i thread!
Ciao ciao!
//: MultiJabberServer.java
// A server that uses multithreading to handle
// any number of clients.
import java.io.*;
import java.net.*;
class ServeOneJabber extends Thread {
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;
    public ServeOneJabber(Socket s)
    throws IOException {
        socket = s;
        in =
        new BufferedReader(
        new InputStreamReader(
        socket.getInputStream()));
        // Enable auto-flush:
        out =
        new PrintWriter(
        new BufferedWriter(
        new OutputStreamWriter(
        socket.getOutputStream())), true);
        // If any of the above calls throw an
        // exception, the caller is responsible for
        // closing the socket. Otherwise the thread
        // will close it.
        start(); // Calls run()
   }
   public void run() {
        try {
        while (true) {
            String str = in.readLine();
            if (str.equals("END")) break;
            System.out.println("Echoing: " + str);
            out.println(str);
        }
        System.out.println("closing...");
        } catch (IOException e) {
        } finally {
            try {
                socket.close();
            } catch(IOException e) {}
        }
    }
}
public class MultiJabberServer {
    static final int PORT = 8080;
    public static void main(String[] args)
    throws IOException {
        ServerSocket s = new ServerSocket(PORT);
        System.out.println("Server Started");
        try {
            while(true) {
                // Blocks until a connection occurs:
                Socket socket = s.accept();
                try {
                    new ServeOneJabber(socket);
                } catch(IOException e) {
                // If it fails, close the socket,
                // otherwise the thread will close it:
                socket.close();
             }
        }
        } finally {
            s.close();
        }
    }
}
by B.

La soluzione è semplice anche se non ha nulla a che vedere con i Socket.
Devi semlicemente mettere il tuo codice "esecutivo" (ciò quello che,
ricevuto un socket fa le operazioni) nel metodo public void run() di
un'altra classe che implementa Runnable. La classe principale non dovrà fare
altro che mettersi in attesa della connessione (con serversockt) e poi
creare una nuova istanza della classe che hai appena sviluppato. In questo
modo potranno esserci più istanze della classe "esecutiva"
contemporaneamente, permettendoti di gestire più socket nello stesso tempo.
Con un uso sapiente dell'avanzatissima tecnica del copia-incolla potrai
rendere la tua applicazione multithreaded in pochi minuti... ;-)
Se avessi problemi fammi sapere, intanto ti saluto
MindFlavor.