Visualizzazione dei risultati da 1 a 3 su 3
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    2

    [JAVA]Utilizzo Socket client/server multithreading

    Salve a tutti sono nuovo del forum, vorrei realizzare un server java multithreading che implementi (per ora) una chat accessibile tramite applet.

    In breve il server usa un ServerSocket.accept() all'interno di un while,e se la connessione è accetata allora lancia un nuovo thread e gli assegna un socket libero per gestire la connessione di un utente.

    L'applet che fa da client (una volta premuto connetti) fa partire il login che se viene accettato lancia un thread che, anche qui gestisce la connessione. Ogni input viene inviato poi al thread se ci sono altri eventi (altri bottoni premuti ecc).

    Per fare in modo però che un client riceva gli aggiornamenti ,senza dover attendere eventi dall'utente, in un singolo ciclo dei while sia del server sia dell'applet faccio un readLine() e un writeBytes() con un Thread.sleep(200) alla fine.Il server interpreta la ricezione solo se diversa da "0" e il client visualizza gli aggiornamenti solo se la ricezione è diversa da "0".In pratica comunicano sempre e svolgono le loro funzioni solo se la stringa ricevuta/inviata è diversa da "0".

    Ora il mio dubbio è questo: se il server non ha aggiornamenti da fare o il client comandi da inviare si consuma cmq banda ad ogni ciclo..

    Sarebbe,secondo voi, un metodo migliore e tecnicamente realizzabile (posso usare due socket per una stessa connessione?) quello di creare due thread separati e due socket per ogni utente, uno solo per la ricezione uno solo per invio (sia sul server sia sull'applet) cosi da fare in modo di far ricevere/inviare solo quando cè effettivamente qualcosa da fare?

    Grazie delle eventuali risposte.
    Satsha.

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [JAVA]Utilizzo Socket client/server multithreading

    Originariamente inviato da Satsha
    In breve il server usa un ServerSocket.accept() all'interno di un while,e se la connessione è accetata allora lancia un nuovo thread e gli assegna un socket libero per gestire la connessione di un utente.
    Ok, non fa una piega.

    Originariamente inviato da Satsha
    Sarebbe,secondo voi, un metodo migliore e tecnicamente realizzabile (posso usare due socket per una stessa connessione?) quello di creare due thread separati e due socket per ogni utente, uno solo per la ricezione uno solo per invio (sia sul server sia sull'applet) cosi da fare in modo di far ricevere/inviare solo quando cè effettivamente qualcosa da fare?
    Quando si lavora con il networking per fare cose di questo tipo, è bene stabilire e avere ben chiaro il "protocollo" di comunicazione che si vuole realizzare. Per "protocollo" si intende, detto in generale, semplicemente che cosa i due host si devono aspettare e/o inviare man mano che la comunicazione prosegue nel tempo.

    Il protocollo più semplice è il classico client-server. Il server resta inizialmente in attesa, il client "sa" che deve mandare subito qualcosa e una volta che il server l'ha ricevuto invia a sua volta una risposta, che il client riceve perché "sa" che in questa fase si deve aspettare lui "qualcosa". E la procedura può poi eventualmente ripartire da capo con il server che aspetta qualcosa dal client.
    Questo è un tipo di comunicazione molto "sincrona", nel senso che la sequenza di invio/ricezione dei dati è sequenziale ed è ben chiara e nota. In ogni momento della comunicazione ognuno dei due host "sa" bene quando deve inviare e quando ricevere dei dati e l'invio o la ricezione, a seconda, è causato da una precedente azione dell'altro host. Per dirla in altre parole, se l'invio di un dato lo immagini come una "pallina", questa pallina è una sola e viaggia da un host all'altro in modo sequenziale. Non c'è mai un momento in cui ci sono 2 "palline" che viaggiano per conto loro una in un senso e l'altra nell'altro!!!

    Nel caso di una chat invece è abbastanza diverso. Immaginiamo il server S e i client A, B, C e D. Se A invia ad S il messaggio "ciao sono pippo", essendo una chat quello che si desidera è che tale messaggio venga "girato" subito a tutti gli altri client B, C e D.

    Questo cambia abbastanza le cose .... perché diventa una comunicazione molto "asincrona". I client B/C/D sanno ovviamente che possono ricevere qualcosa (sono client di una chat ... no?) ma non sanno esattamente quando!!! E la ricezione non è dovuta ad una loro azione/invio precedente!
    Questo è appunto il caso in cui 2 "palline" possono viaggiare contemporaneamente in un senso e nell'altro.

    In casi come questi è necessario gestire separatamente i due flussi di comunicazione invio e ricezione. Un Socket ha appunto 2 stream: un InputStream e un OutputStream. Cosa fa pensare questo? Che è necessario avere 2 thread uno per la gestione dell'invio e l'altro per la ricezione. Ma il Socket è comunque 1 solo. Non è certo necessario avere 2 Socket!!!

    Una gestione di questo tipo ovviamente complica un po' le cose, specialmente sul server. Perché anche sul server, per ogni comunicazione con il client, è necessario avere 2 contesti separati per la gestione di invio/ricezione. E quando sul server, da un thread di ricezione, viene ricevuto "qualcosa" bisogna fare in modo che esso venga dato a tutti gli altri thread che si occupano dell'invio al rispettivo client.
    Ovviamente non lo si fa direttamente, cioè nel thread di ricezione non si invia direttamente sugli stream di output delle altre comunicazioni!!!

    In questi casi è bene usare strutture dati più complesse, come delle code. Per ogni thread per l'invio al client c'è associata una coda. Il thread semplicemente in loop attende/legge dalla coda ed invia a client. Quando da un thread di ricezione si riceve qualcosa bisogna passarlo a del codice che "sa" di tutte le code cosicché lo passa a tutti quanti. E chiaramente va gestita opportunamente la "sincronizzazione" tra i thread.

    Questo è solo un esempio, giusto per far capire la maggiore difficoltà per una gestione di questo tipo.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    2
    Grazie mille della risposta!!!!

    La chat effettivamente rispecchia il protocollo delle due palline.

    Ho pensato a due socket (inizialmente pensavo anchio a uno) solo perchè ogni volta che un thread lo usa (in ricezione o in uscita) dovrebbe avere l'accesso esclusivo su di esso e quindi l'altro thread dovrebbe aspettare che finisca, anche se non ero sicuro di questa cosa visto che usano i 2 stream separati come hai scritto.


    Per l'invio dei messaggi agli altri trhead avevo pensato ad un array static di utenti condiviso tra tutti i trhead.Ogni utente ha una stringa che viene scritta in base ai messaggi ricevuti dai singoli thread e dagli utenti presenti nella stessa stanza.(quando un utente entra in una stanza gli viene associata). Quando il thread da output del client e utente specifico rileva che la stringa dell'utente non è di lunghezza 0 (ad esempio) allora lo invia in uscita e azzera la stringa.Il tutto con i relativi accessi esclusivi da parte dei thread.

    Darò un'occhiata anche alle code per farmi un'idea di come si potrebbe implementare
    quello che hai detto alla fine.

    Satsha.

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 © 2025 vBulletin Solutions, Inc. All rights reserved.