Client Server protocollo TCP

di il
4 risposte

Client Server protocollo TCP

CIao a tutti, sono nuovo.
Programmo da 4 anni in Java anche se solo nell'ultimo anno, frequentando la Facoltà di Ingegneria Informatica, ho iniziato a programmare seriamente.
Ho cercato un po' su questo forum ma non ho trovato la risposta al mio quesito, quindi ho creato un nuovo argomento. Se per caso ho sbagliato e l'argomento era già stato trattato vi prego di indicarmi il link dell'argomento. Comincio a spiegare..

Sto creando un'applicazione client server tramite protocollo TCP (premetto che questo non me lo hanno spiegato in facoltà e me lo sono visto da solo tramite JavaDoc, altri siti e manuali).
Ho già creato il client e il server e la rispettiva connessione fra i due; ho fatto in modo che il server possa inviare OGGETTI al client tramite gli stream: ObjectInputStream e ObjectOutputStream (l'input del client è collegato all'output del server per intenderci) e trasferisco gli oggetti tramite la writeObject() e li "ricostruisco" con la readObject(). Fin qui tutto bene.
Il problema sta nel fatto di trasferire un oggetto JFrame, o una sua sottoclasse da me implementata o un altro mio oggetto che contenga una JFrame. Questa finestra una volta ricostruita e la rendo visibile, ma le sue "funzionalità" sono ridotte, ovvero che i bottoni (JButton) quando vengono premuti non attivano il relativo ActionListener() al quale erano connessi.

Ho provato sia a creare un ActionListener separato (una classe vera e propria, a parte rispetto all'oggetto in cui ho il pulsante), ma anche a creare una classe interna all'oggetto(come fanno di default parecchi IDE).

// classe esterna (non so se sono stato chiaro quindi posto il codice)
public class MyActionListener implements ActionListener{
	@Override
	public void actionPerformed(ActionEvent e) {
		// istruzioni da eseguire
	}});
}

// classe interna
bottone.addActionListener(new ActionListener(){
	@Override
	public void actionPerformed(ActionEvent e) {
		// istruzioni da eseguire
	}});
Premetto che non sto utilizzando i Thread perché non ho molta confidenza con queste classi.
io utilizzo le classi:
- java.net.Socket
- java.net.ServerSocket

Se qualcuno ha già riscontrato il mio problema o sappia come risolverlo mi dia un consiglio.
Gliene sarei molto grato :3

Per ora ringrazio tutti per la futura risposta e spero di essere stato chiaro.

4 Risposte

  • Re: Client Server protocollo TCP

    kevkev ha scritto:


    Il problema sta nel fatto di trasferire un oggetto JFrame, o una sua sottoclasse da me implementata o un altro mio oggetto che contenga una JFrame.
    Personalmente questo te lo sconsiglio ... e molto altamente. Tra l'altro, serializzare oggetti di GUI (e addirittura una finestra con magari decine di componenti) fa serializzare una quantità "spropositata" di proprietà.

    Dovresti trasferire dati, non oggetti visuali.
  • Re: Client Server protocollo TCP

    andbin ha scritto:


    Il problema sta nel fatto di trasferire un oggetto JFrame, o una sua sottoclasse da me implementata o un altro mio oggetto che contenga una JFrame.
    Personalmente questo te lo sconsiglio ... e molto altamente. Tra l'altro, serializzare oggetti di GUI (e addirittura una finestra con magari decine di componenti) fa serializzare una quantità "spropositata" di proprietà.

    Dovresti trasferire dati, non oggetti visuali.
    Mhmm ok, forse il problema è che si perdono informazioni, non pensavo fosse un problema trasferire oggetti grafici tramite serializzazione (ma in effetti diventerebbe un trasferimento consistente di dati, non ci avevo pensato u.u).

    Questo problema deriva dal fatto che sto cercando di creare il gioco del Memory due giocatori e perciò volevo creare la schermata di gioco una volta sola (sul server) e spedirla ad entrambi i client.
    A questo punto mi consigli di fare le elaborazioni sul server e spedire i dati per la costruzione della finestra sul client (ad entrambi) cosi che possano creare la schermata di gioco (IDENTICA!!!) e possano agire su di essa?
  • Re: Client Server protocollo TCP

    kevkev ha scritto:


    forse il problema è che si perdono informazioni
    È perfettamente possibile che si perdano i listener agganciati. E ti spiego anche il perché (e il senso del "possibile").

    Ciascun componente Swing utilizza un oggetto EventListenerList per contenere tutti i listener registrati sul componente, di tutti i tipi in modo eterogeneo (questo è stato fatto per risparmiare memoria). All'interno di EventListenerList c'è un campo array per i listener ma è "transient". Non è serializzato direttamente perché c'è il writeObject privato per la serializzazione "custom". Al cui interno fa:
                EventListener l = (EventListener)lList[i+1];
                if ((l!=null) && (l instanceof Serializable)) {
                    // .....
                    s.writeObject(l);
                }
    È chiaro cosa fa? Serializza l'oggetto che implementa il listener ma SOLO se implementa anche Serializable.
    Siccome ad esempio è molto facile (e tipico, lo faccio sovente anche io) usare anonymous inner-class per implementare un listener, visto che implementa già un XyzListener, allora non può derivare anche da Serializable. Pertanto in tutti questi casi li perderesti.

    Anche se definisci tutte le implementazioni dei listener come Serializable, potresti arrivare a serializzare dello "stato" che o è troppo oppure è inappropriato per il proseguimento della applicazione.

    kevkev ha scritto:


    ma in effetti diventerebbe un trasferimento consistente di dati, non ci avevo pensato u.u).
    Per curiosità, hai provato a fare una prova veloce:
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("frame.ser"));
    oos.writeObject(new JFrame());
    oos.close();
    Cioè serializzare un JFrame praticamente vuoto! A me viene fuori un file di 6012 byte. A parte i 4 byte fissi di "header" della serializzazione, vuol dire che il frame serializzato occupa 6008 byte, cioè 5,8 KByte .... praticamente una "eresia".

    Inoltre dal javadoc di una classe Swing es. JFrame si legge:

    Warning: Serialized objects of this class will not be compatible with future Swing releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Swing.

    Quindi se il tuo server usa una certa versione di Java e i client ne usano un'altra .... puoi anche avere problemi di incompatibilità.

    kevkev ha scritto:


    Questo problema deriva dal fatto che sto cercando di creare il gioco del Memory due giocatori e perciò volevo creare la schermata di gioco una volta sola (sul server) e spedirla ad entrambi i client.
    Purtroppo questo (oltre a quanto detto sopra) non giustifica affatto la serializzazione (di oggetti grafici, nota bene) "solo per far vedere agli utenti la stessa cosa".

    kevkev ha scritto:


    A questo punto mi consigli di fare le elaborazioni sul server e spedire i dati per la costruzione della finestra sul client (ad entrambi) cosi che possano creare la schermata di gioco (IDENTICA!!!) e possano agire su di essa?
    Sì.
  • Re: Client Server protocollo TCP

    SIsi, capisco ciò che intendi dell'ActionListener ecc.
    Grazie mille Andbin, ora provo a fare come dici e ti farò sapere.
    Grazie ancora per questi consigli! Ne farò buon uso (spero)!
    Buona serata :3
Devi accedere o registrarti per scrivere nel forum
4 risposte