Visualizzazione dei risultati da 1 a 9 su 9

Discussione: Chat con Java

  1. #1

    Chat con Java

    salve
    sono alle prime armi con java.net, sto cercando di creare un server che fà comunicare vari Telnet come una chat, il problema è che non so come poter ricevere e inviare contemporaneamente messaggi.
    Mi spiego il programma server, crea due buffer associati ad un socket, uno in entrata e uno in uscita, il problema è che il server è in attesa che qualcosa arrivi dal buffer e non può introdurre niente nel buffer di uscit afinchè il client non gli invia niente.
    Insomma la chat è sincrona,finchè uno non scrive l'altro non puo' farlo.
    Non mi rispondete semplicemente usa i Thread, perchè ciò provato, quindi magari se questa era la strada giusta vi ringrazierei se mi deste qualche dritta in piu'.


    grazie

  2. #2
    Utente di HTML.it
    Registrato dal
    Mar 2002
    Messaggi
    315
    Non mi rispondete semplicemente usa i Thread, perchè ciò provato, quindi magari se questa era la strada giusta vi ringrazierei se mi deste qualche dritta in piu'.
    Direi che ti sei risposto da solo :gren:
    A parte gli scherzi una soluzione semplice puo' essere questa:
    Crea un oggetto MainServer che rimane in ascolto su di una porta, in attesa che dei client vi si connettano.
    Ogni volta che un client si connette il MainServer crea un oggetto socket per poter dialogare con il client: il problema (che tu stesso hai riscontrato) e' che se il server si mette a comunicare con quel client chiunque altri provi a connettersi troverebbe la porta occupata.
    Per evitare questo quando il MainServer crea il socket lo passa poi ad un altro oggetto che si incarica di utilizzarlo.
    Es:
    codice:
    class MainServer implements Runnable {
      private int thePort;
      private ServerSocket theSocket;
      private boolean done=false;
      private Thread theThread;
    
      MainServer( int port) {
        thePort = port;
      }
    
      public void run() {
        //esce se il metodo viene chiamato dall'esterno
        if(Thread.currentThread != theThread) return;
        while(!done) {
          try {
            //il metodo accept() restituisce un socket associato
            //al client appena connessosi
            new ConnManager( theSocket.accept());
          } catch(IOException eIO) {}
        }
      }
    
      //l'unico modo per far partire il MainServer
      //e' chiamare start()
      public void start() 
        throws IOException
      {
        theSocket = new ServerSocket(thePort);
        theThread = new Thread(this).start;
      }
    
      //Per buona creanza ricordarsi di chiamare stop()
      public void stop() {
        done = true;
        if(theThread != null && theThread.isAlive())
          theThread.interrupt();
        try {
          theSocket.close();
        } catch(IOExcpetion eIO) {}
      }
    }
    In questo stralcio, come vedi, il MainServer non fa altro che attendere nuovi client, per passarli ad un altro oggetto, di tipo ConnManager, il quale si preoccupera' di dialogare con il client secondo un protocollo che stabilisci tu.

    Chiaramente questa soluzione e' mooolto grezza, ma lascia spazio ad ampi margini di miglioramento, a seconda di quello di cui hai bisogno.
    Buon lavoro.
    Ciao,
    Lorenzo

  3. #3
    Grazie molte mi metto subito al lavoro.

    ciao

  4. #4
    Però leggendo bene il tuo listato, forse non mi sono spiegato, infatti il mio reale problema non è che ci sono piu' client.
    Mettiamo che ci sia un solo client, il fatto è che se il server ha un buffer in attesa di dati (in questo caso stringhe), come può un utente che vuole scrivere un messaggio dal server che arrivi al client ?? (infatti l'OUT non può essere inviato se il server ha il buffer in attesa in entrata).

    grazie

  5. #5
    Per farti capire ancora meglio:
    anche se lancio due thread, uno che si occupa dell'invio e uno della ricezione, essi non funzioneranno mai insieme e quindi il tutto non funziona come una chat che io posso inviarti anche due stringhe una dopo l'altra prima che tu mi risponda.
    ciao

  6. #6
    A me coi thread funziona tutto a meraviglia!!
    Rivedi il tuo progetto!
    Avrai fatto qualche erore concettuale...
    Blink@go

    "Non tutto quel che è oro brilla, Ne gli erranti sono perduti; Il vecchio ch'è forte non s'aggrinza, Le radici profonde non gelano.Dalle ceneri rinascerà un fuoco, L'ombra sprigionerà una scintilla, Nuova sarà la lama ormai rotta, E re quei ch'è senza corona."

    ------------
    Lang: java 1.4.1 Eclipse

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2002
    Messaggi
    315
    Ho capito qual e' il tuo problema. La soluzione e' fare interagire i due thread con un semaforo.
    Potresti strutturare la cosa in questo modo:
    un thread e' quello del server, che si occupa di ricevere i messaggi dai client, che poi deve ridistribuire (quindi non mi riferisco a quello che riceve le connessioni, qui non ne tengo conto).
    Questo thread rimane in attesa su un semaforo: fino a che questo e' disattivato il thread rimane in stato di wait.
    Il client, invece, e' composto da 2 thread: uno che rimane in ascolto sul socket per vedere se un utente ha spedito un messaggio, l'altro rimane anch'esso in attesa su un semaforo.
    Quando un utente invia un messaggio, il thread del client incaricato della ricezione lo memorizza. A quel punto passa il messaggio al server, attiva il semaforo (sempre del server) e sveglia il thread. Poi si rimette in ascolto sulla porta, in attesa di altri messaggi.
    Il thread del server, una volta uscito dallo stato di wait, si accorge del semaforo attivo, lo disattiva di nuovo e va a leggere il messaggio. Quindi si occupa di reindirizzarlo a tutti i client (tranne, ovviamente, a quello che l'ha spedito).
    Per spedire il messaggio ai client compie le stesse operazioni di prima: invia il messaggio ai client (mi riferisco ai client risiedenti sulla macchina "server", scusa il gioco di parole, non a quelli remoti degli utenti), attiva il semaforo del thread in attesa e poi lo sveglia.
    Il client, a quel punto, si trova con due thread attivi: uno che continua ad attendere i messaggi, e l'altro che finalmente ha qualcosa da fare: spedire al client remoto il messaggio (dopo aver disattivato il semaforo, ovviamente).

    Come soluzione mi sembra la piu' accettabile: in termini di prestazioni un thread in stato di wait non consuma cicli macchina, semmai e' oneroso in termini di memoria... e' un compromesso da vagliare. Devi un po' darti da fare per quanto riguarda la sincronizzazione dei thread, ma come idea credo che funzioni.
    Ciao,
    Lorenzo

  8. #8
    Hai centrato il punto, ti ringrazio per la tua articolatissima risposta, si penso che sia il caso di fare come dici te.
    Proprio una bella pensata.
    ciao

  9. #9
    hai provato anche a dare un'occhio al progetto jxta?
    é un progetto per il p2p in java, dovrebbe funzionare anche dietro proxy e firewall


    mandi
    23-08-2005: Udinese in cémpions lìg
    Questa estate l'ho passata a Tallin

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.