Programmazione di rete[JAVA]

di il
28 risposte

Programmazione di rete[JAVA]

Salve,
Sto tentando di creare una chat in java.
Ho già scritto il server multithread per gestire più client, e anche la parte client.
Ciò che non riesco a capire è come poter inviare ciò che viene scritto da un client a tutti gli altri client.
Sono riuscito a mandare l'ipotetica frase da scrivere al server, ma non riesco ad inviarla a tutti i client, ma solamente a quello che l'ha inviata al server ( perché il codice che esegue ciò è all'interno del thread che gestisce quel determinato client).
Qualcuno sa suggerirmi una soluzione? Grazie.

28 Risposte

  • Re: Programmazione di rete[JAVA]

    JAVA2222 ha scritto:


    Ho già scritto il server multithread per gestire più client, e anche la parte client.
    Innanzitutto avendo sul server una architettura multi-thread, DEVI assolutamente avere le idee chiarissime su tutte le questioni legate alla concorrenza, sincronizzazione (con il lock intrinseco degli oggetti o altro), "visibilità" delle modifiche, uso (eventuale) di collezioni thread-safe, ecc...

    JAVA2222 ha scritto:


    Ciò che non riesco a capire è come poter inviare ciò che viene scritto da un client a tutti gli altri client.
    Questo dipende molto dalla architettura generale. Sul server ciascun client è servito da 1 thread al cui interno gestisci la connessione socket TCP che è quindi "permanente" per la durata della connessione dal client?
    Allora si presume che ciascun thread abbia un "loop" in cui stia (quasi) perennemente in attesa di qualcosa dal rispettivo client. E quindi se ne deduce che NON è questo thread che può inviare qualcosa che arriva da altri client.

    Con una architettura del genere, si potrebbe avere 1 ulteriore thread X che invia il messaggio a TUTTI i client. Quando da un thread viene ricevuto un messaggio, questo potrebbe essere "dispacciato" al thread X ad esempio tramite una coda sincronizzata. Il thread X scoda il messaggio e lo invia a TUTTI i client. Come fare in modo che il thread X abbia le nozioni utili per inviare il messaggio su tutti i socket relativi ai client, è un altro discorso. Ma si può fare.
  • Re: Programmazione di rete[JAVA]

    Mi scuso per non avere tutte le conoscenze in merito ai thread ma sono in prima superiore e ho iniziato a programmare in java quest'anno.
    Comunque, l'architettura del programma è propria quella descritta da lei, che quindi come ho capito non è quella giusta per riuscire nel mio scopo.
    Ho capito circa cosa intende per la creazione di un thread X che gestisca la trasmissione dei dati a tutti i client, ma sa dirmi da dove iniziare per crearlo? Grazie.
  • Re: Programmazione di rete[JAVA]

    JAVA2222 ha scritto:


    che quindi come ho capito non è quella giusta per riuscire nel mio scopo.
    No, va anche bene ma serve anche qualcos'altro.

    JAVA2222 ha scritto:


    Ho capito circa cosa intende per la creazione di un thread X che gestisca la trasmissione dei dati a tutti i client, ma sa dirmi da dove iniziare per crearlo?
    Crei un thread a parte, singolo e distinto da tutti gli altri N che vengono creati per gli N client. Questo thread si occuperà di inviare il messaggio a tutti i client.
  • Re: Programmazione di rete[JAVA]

    Grazie per la risposta. Sa dirmi qual è il metodo, la funzione per inviare qualcosa a tutti i client?
    Per il flusso output-input tra server e 1 client utilizzo un ObjectOutputStream, ma per inviare qualcosa a tutti i client come faccio?(Intendo appunto il comando da utilizzare all'interno del thread separato)
  • Re: Programmazione di rete[JAVA]

    JAVA2222 ha scritto:


    Sa dirmi qual è il metodo, la funzione per inviare qualcosa a tutti i client?
    Non è che c'è un metodo così ... su due piedi. Lo devi "architettare" tu. Come inviare ad un singolo client presumo lo sai già fare. Devi modellare le cose per cui il thread di "invio" abbia tutte le nozioni per poter inviare lo stesso messaggio a tutti i client. Questo potrebbe voler dire ad esempio tenere una lista o direttamente degli stream di output oppure di tuoi oggetti che incapsulano lo stream e semplificano l'invio. Dipende dal "design" generale.

    JAVA2222 ha scritto:


    Per il flusso output-input tra server e 1 client utilizzo un ObjectOutputStream
    Se usi la serializzazione degli oggetti (per quale motivo?) attenzione al "caching" degli oggetti che viene fatto da writeObject e dalla controparte readObject.
  • Re: Programmazione di rete[JAVA]

    Ma una lista di stream di output a che tipo appartiene?
  • Re: Programmazione di rete[JAVA]

    Ho creato un thread a parte, in cui ho definito una lista con gli ObjectOutputStream.
    Ogni volta che, alla connessione di un client, si apre il relativo thread, aggiungo alla lista un ObjectOutputStream relativo a quel thread.
    Quando un client scrive qualcosa faccio partire il thread per comunicarlo, ma viene generata un' eccezione di tipo IOException, e il programma si blocca. Qualcuno sa dirmi perché?

    Questo è il codice del thread che comunica il messaggio a tutti:

    class Comunicate extends Thread{
    public static ObjectOutputStream[] oggetti=new ObjectOutputStream[30];
    private String message;
    public Comunicate(String mess){
    this.message=mess;
    }
    public void run(){
    try{
    for(ObjectOutputStream i : oggetti){
    i.writeObject(message);
    }
    }catch(IOException e){
    e.printStackTrace();
    }
    }
    }
  • Re: Programmazione di rete[JAVA]

    JAVA2222 ha scritto:


    Quando un client scrive qualcosa faccio partire il thread per comunicarlo}
    No, non va bene come concetto. E non va bene un array e non va bene tenerlo come "static".
  • Re: Programmazione di rete[JAVA]

    E cosa devo usare allora?
  • Re: Programmazione di rete[JAVA]

    Bhè, per inciso, dipende se ti trovi in ambito LAN o WAN. Nel primo caso basterebbe un broadcast.
    very quick, and very dirty.
  • Re: Programmazione di rete[JAVA]

    Grazie, ho risolto quel problema.
    Ora però voglio che il client mandi un messaggio al server solo quando viene premuto un pulsante.
    Il problema è che il server dà un errore sulla' input_stream.readObject(), perché il server rimane costantemente in ascolto di messaggi del client, ma questo non li invia sempre (solo quando viene premuto il pulsante).
    L'errore è questo:
    
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2626)
    	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1321)
    	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
  • Re: Programmazione di rete[JAVA]

    JAVA2222 ha scritto:


    Ora però voglio che il client mandi un messaggio al server solo quando viene premuto un pulsante.
    Ok, ma la comunicazione verso il server deve essere già stata stabilita (in una fase prima) e a quel punto, ogni volta che l'utente preme un tasto di "invio" semplicemente tu mandi il messaggio al server sullo stream di uscita già stabilito.
    Non ci sono problemi grossi per questo, chiaramente vanno considerate le solite cose eventualmente sul threading (l'evento di un pulsante è dispacciato nel Event Dispatch Thread) e su come realizzare la cosa nella maniera perlomeno pulita e logica.

    JAVA2222 ha scritto:


    perché il server rimane costantemente in ascolto di messaggi del client
    Ma infatti è giusto che sia così.
  • Re: Programmazione di rete[JAVA]

    Il fatto è che il server ha un ciclo while(true) dentro il quale c'è un comando tipo String messaggio=(String)input_stream.readObject(), ma appena il server arriva a quel punto, non essendoci nessun messaggio perché il client non ha ancora premuto il pulsante per inviarlo, si blocca e dà l'errore che ho riportato nel messaggio prima, ma non capisco perché.
  • Re: Programmazione di rete[JAVA]

    A parte il "terribile" busy waiting, inizierei a chiedermi cos'è esattamente input_stream.
    Poi mi chiederei se c'è un readObject() (cioè cosa ritorna esattamente, nel caso in cui non vi sia nulla).
    Infine cosa fa String messaggio=(String)qualcosa?
Devi accedere o registrarti per scrivere nel forum
28 risposte