Pagina 1 di 4 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 37
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327

    Semplicissima chat grafica si blocca

    Eccomi di nuovo qua, grazie all'aiuto di LeleFT in un post poco sotto ho risolto i problemi circa la realizzazione di una semplice chat.
    Adesso sto provado a implementarla graficamente, ma il programma rimane bloccato in esecuzione con il pulsante Connect premuto, vi sarei infinitamente grato se anche questa volta mi deste una mano

    Ecco graficamente di che si tratta:


    Il mio intento è quello di, ogni volta che si inserisce il testo nell'apposita area, di far spuntare nella history:
    Client said: text
    Server received: text

    Tuttavia bloccandosi non appena tento la connessione non mi è neppure permesso scrivere.
    Ecco il codice.

    Codice associato al tasto Connect:
    codice:
    Server objs=new Server();
    objs.connect;
    Codice associato al tasto Send:
    codice:
    Client objcl=new Client();
    jTextArea2.append("Client said:"+objc.client(jTextArea1.getText()));
    jTextArea2.append("Server received" + objs.server());
    Ecco il Client
    codice:
    package chat_v01;
    import java.net.*;
    import java.io.*;
    
    public class Client
    {
        String text;
        BufferedReader dalServer;
        PrintWriter alServer;
        public String client(String text)
        {
            this.text=text;
            try
            {
                
                Socket s1 = new Socket ("127.0.0.1", 5555);
                dalServer = new BufferedReader(new InputStreamReader(s1.getInputStream()));
                alServer= new PrintWriter(s1.getOutputStream(),true);
                alServer.println(text);
                if(text.equals("bye"))
                {
                    s1.close();
                }
            }
            catch (ConnectException connExc)
            {
                System.err.println("Errore nella connessione ");
            }
            catch (IOException ex)
            {
                ex.printStackTrace();
            } 
            return text;
        }
    }
    Ecco il server:
    codice:
    package chat_v01;
    import java.net.*;
    import java.io.*;
    
    public class Server 
    {
        BufferedReader dalClient;
        PrintWriter alClient;
        Socket sse;
        public ServerSocket server = null;
        public void connect()
        {
            
            try
            {
                server = new ServerSocket(5555);  
                sse = server.accept();
                dalClient=new BufferedReader(new InputStreamReader(sse.getInputStream()));
                alClient= new PrintWriter(sse.getOutputStream(),true);
            }
            catch (IOException ex)
            {
                ex.printStackTrace();
            }
            
        }
            
        public String server()
        {
            String text = null;
            try
            {
                text=dalClient.readLine();
                if (text.equals("bye"))
                {
                    sse.close();
                }
            }
            catch (IOException ex)
            {
                ex.printStackTrace();
            }
            
             return text;
        }
    }

    Grazie come sempre a tutti coloro che mi vorranno aiutare!

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Client (e Server, se necessario) devono girare in un Thread separato... anzi, dovrebbero essi stessi essere dei Thread, altrimenti, venendo eseguiti nel contesto del'EDT, lo tengono impegnato rendendo, appunto, bloccata l'interfaccia grafica.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    più che thread separati, applicazioni separate (visto che in genere risiedono anche su pc differenti)
    RTFM Read That F*** Manual!!!

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Mi spiego meglio...

    Il client dovrebbe essere composto da due entità: una GUI e un Thread (la tua classe Client).
    La GUI dovrebbe occuparsi di avviare il thread che gestisce il client.

    Stessa cosa per il Server (se il server dispone di una GUI).

    Spero poi che, come dice valia, le due cose stiano anche in applicazioni separate...


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327
    Grazie per le vostre risposte anzitutto
    Sto ragionando su quello che mi hai detto, ma non mi è molto chiaro, ho le idee un pò confuse a livello concettuale, provo a chiarirmele e scrivo ciò a cui sono arrivato e definita almeno l'idea provo a fare tutto da capo.
    Per quanto riguarda il fatto che debbano essere due applicazioni separate (client e server) quello sarà il passo successivo al momento vorrei realizzare un'unica interfaccia grafica che mostri ciò che il client scrive e ciò che il server riceve.

    Continuo a non capire perchè si blocca quando premo connect, avrebbe senso se si bloccasse quando mando nella jTextArea ciò che il client digita visto che non ho usato il multithread, ma non quando premo connect che nulla ha a che fare con la grafica no?

  6. #6
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327
    Eccomi
    L'obiettivo è scrivere del teso nella gui (sarebbe il client che scrive), inviarlo al server, veder comparire nella Gui il testo inviato dal client e quello ricevuto dal server (ovviamente è lo stesso testo).
    La connessione deve essere instaurata all'inizio e una volta che le socket sono comunicanti rimangono in tale stato finchè il client non cessa di esistere.

    Per realizzare questo dici che mi posso muovere nel seguente modo?

    Tre classi: Gui - Server - Client

    Classe Gui: dotata di due pulsanti, uno per stabilire la connessione, l'altro per, nell'ordine:

    1) Prendere il testo inserito nella TextArea inviarlo alla classe Client la quale la invia al Server
    2) Adoperare un'apposita funzione presente nella classe Client per mandare in stampa il testo.
    3) Adoperare un'apposita funzione nella classe server per mandare in stampa quanto ricevuto dal client.

    Più o meno è così?
    Se così fosse, cosa deve essere gestito in thread distinti?
    Io credo le ultime due funzioni di cui parlo nei punti 2) e 3) per il resto non ci dovrebbero essere problemi, no?

  7. #7
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327
    Ok dopo un pò di ore ce l'ho fatta!!!!!
    Ho riscritto il codice da capo, più pulito lineare e chiaro.
    Funziona quasi, quasi nel senso che solo per il primo flusso di messaggi si ha il corretto funzionamento (la prima volta che si clicca su send), la seconda volta invece si blocca.

    Credo di sapere quale sia il motivo, ovvero il fatto che quando per la seconda volta chiamo il metodo fromClient nella classe Server questo cerca di fare nuovamente
    codice:
    s1 = server.accept();
    Ecco il codice:
    Codice associato al tasto connessione:
    codice:
    objS.connect(jTextField2.getText());  //objS e objC sono stati dichiarati sopra e permettono
                                                      //di chiamare i metodi delle classi Client e Sever
    objC.connect(jTextField1.getText(),jTextField2.getText());
    Codice associato al tasto send:
    codice:
    objC.getText(jTextArea2.getText());
    objC.toServer();
    jTextArea1.append(objC.toPrint()+"\n");
    jTextArea2.setText("");
    objS.fromClient();
    jTextArea1.append(objS.toPrint()+"\n");
    Client
    codice:
    package chat_v01;
    import java.net.*;
    import java.io.*;
    
    public class Client
    {
        String ip;
        String port;
        Socket s1;
        public void connect( String ip, String port )
        {
            this.ip=ip;
            this.port=port;
            int ponumber=Integer.parseInt(port);
            
            try
            {
                s1 = new Socket (ip, ponumber);
            }
            catch (ConnectException connExc)
            {
                System.err.println("Errore nella connessione ");
                
                
            }
            catch (IOException ex)
            {
                ex.printStackTrace();
                
                
            }
        }
        
        String text;
        public void getText(String text)
        {
            this.text=text;
        }
        
        public void toServer()
        {
            try
            {
                //BufferedReader dalServer = new BufferedReader(new InputStreamReader(s1.getInputStream()));
                PrintWriter alServer= new PrintWriter(s1.getOutputStream(),true);
                alServer.println(text);
            }
            catch (ConnectException connExc)
            {
                System.err.println("Errore nella connessione ");
                
                
            }
            catch (IOException ex)
            {
                ex.printStackTrace();
                
                
            }
            
        }
        
        
        public String toPrint()
        {
            
            String finaltext="Client said: "+text;
            return finaltext;
        }
    }
    Server
    codice:
    package chat_v01;
    import java.net.*;
    import java.io.*;
    public class Server 
    {
        String port;
        Socket s1;
        ServerSocket server;
        
        public void connect(String port)
        {
            this.port=port;
            int portnumber=Integer.parseInt(port);
            try
            {
                server=new ServerSocket(portnumber);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            
        }
        
        BufferedReader dalClient;
        String text;
        public void fromClient()
        {
            try
            {
            s1 = server.accept();
            dalClient=new BufferedReader(new InputStreamReader(s1.getInputStream()));
            text=dalClient.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
        
        
        public String toPrint()
        {
            
            String finaltext="Server said: "+text;
            return finaltext;
        }
        
        
    }
    Ho pensato di risolvere il problema spostando
    codice:
    s1 = server.accept();
    all'interno del metodo connect della classe Server di modo tale che venisse invocato solo una volta.. Tuttavia in questo modo il programma si impalla già immediatamente quando viene premuto il tasto connetti.
    Ci sono quasi mi date un'ultima spinta?

  8. #8
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    Ci sono due classi di problemi che devi affrontare, magari se segui un po' quello che adesso ti dico capisci quello che io e leleft vogliamo dirti.

    1. applicazioni differenti. Il modello di comunicazione client/server è strutturato in modo da avere due applicazioni differenti, in genere su due computer differenti, che comunicano tra loro. Tipicamente il server fornisce un servizio, il client ne usufruisce. La comunicazione è iniziata dal client che invia una richiesta al server, il quale risponde con il risultato della richiesta.
    Il fatto che tu logicamente non sai separare (o non vuoi) ti porta ad errori nella gestione del tutto. Passo numero 1 quindi è scrivere 2 applicazioni, un server e un client.
    Rivedi alla base la logica su client e server, il tuo server non va perché è in grado di gestire una sola connessione (Cosa non vera) e soprattutto termina scritto il messaggio (cosa non corretta, dovrebbe terminare su richiesta di close o di errore)
    2. se tu hai una chat, in realtà hai 2 client che vogliono comunicare tra loro, il server si limita ad offrire la "stanza" su cui entrambi scrivono.
    Tecnicamente un test valido è fatto da 3 esecuzioni, 1 server e 2 client
    3. per il momento lascia perdere la grafica e fai funzionare tutto visualizzando i messaggi a riga di comando. Questa semplificazione te la consiglio in un primo momento perché devi separare le classi dei problemi. In realtà la logica dell'applicazione client/server cambia poco se fai log su file, su console o su GUI, quindi se riesci a mettere su il motore, ti viene più facile capire come far funzionare tutto.
    In realtà tu non stai separando la logica dalla grafica, la grafica è solo UNO dei modi di visualizzare il tutto e di far funzionare il tutto, non so se riesci a seguirmi.
    Alla parte grafica deve arrivare solo il messaggio da scrivere, è la parte che si occupa dei controlli a reperire cosa scrivere.
    Questo in realtà è un progetto corposo, che ti chiede un minimo di conoscenze su tutta la java SE.
    RTFM Read That F*** Manual!!!

  9. #9
    Utente di HTML.it
    Registrato dal
    Nov 2007
    Messaggi
    327
    Sono d'accordo con te e ho capito perfettamente, sono necessari almeno due client e le applicazioni devono essere separate affinché si abbia una ragionevole funzionamento e forse anche un'implementazione più lineare.
    Tuttavia la consegna che mi è stata data all'università è stata questa e quindi è questo che devo fare, quello di implementare la chat reale (con più client e un server che possa accettare più connessioni contemporaneamente) è lo step successivo.

    Per quanto riguarda il fatto che la Gui non ho fatto come dici tu?
    Si occupa solo di far visualizzare il testo, tutte le operazioni sono delegate alle altre due classi, però dalla GUI devo comunque invocarle per far eseguire le operazioni.

  10. #10
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    Non hai capito.
    Intanto la tua implementazione prevede una sola connessione e già questo basta a capire che non hai chiaro come funziona un server.
    Banalmente ci vuole un ciclo infinito che è sempre in attesa di una connessione, ricevuta una connessione avvia un thread che gestisce la comunicazione con il client x e si rimette in ascolto della successiva connessione.
    Alla base è quindi scorretto il server (quindi ti porta ad altri errori).

    Ti ho detto di scrivere i log su console per isolare le fonti di errore: tutto quello che tu scrivi in realtà è indipendente dalla destinazione, quindi se al momento scrivi su console male non fai. in un secondo momento metti la grafica, ma è buona norma introdurre un livello di difficoltà per volta (e quindi anche una sola causa di errore per volta).
    Fai funzionare tutto da console, poi aggiungi la scrittura su textArea, ma almeno sai che alla base tutto funziona, qui non sai nemmeno fare l'infrastruttura di base.

    La consegna è una, e sono d'accordo con te. Io non ti sto dicendo di non rispettarla, ti sto dicendo di separare la classe dei problemi, in modo da dover affrontare un problema e un errore per volta.
    Per adesso non sai far funzionare la base, non puoi scopiazzare codice mettendo tutto insieme e sperando che vada (andando a tentativi come vedo).
    RTFM Read That F*** Manual!!!

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.