Visualizzazione dei risultati da 1 a 7 su 7

Discussione: Read non bloccante

  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2010
    Messaggi
    13

    Read non bloccante

    Buonasera a tutti,
    sto creando un'applicazione java dove devo gestire la disconnessione utenti.
    Il mio problema è che l'evento di disconnessione "non arriva" perché sono ferma su una read...
    Ecco il codice:

    codice:
    public class ThreadDisconnessioneClient extends Thread {
    	private GuiPrivatoClient guiClient;
    	private Socket stato;
    	BufferedReader in;
    	PrintWriter out;
    	String esito;
    	private ClientMain client;
    	private boolean disconnetti;
    	
    	public ThreadDisconnessioneClient(GuiPrivatoClient gui, Socket s, ClientMain cm){
    		guiClient = gui;
    		stato = s;
    		client = cm;
    		disconnetti = client.terminaChiamata;
    	}
    	
    	public void run(){
    		System.out.println("ho avviato thread disconnessione client");
    		while(disconnetti == false){
    			try {
    				in = new BufferedReader(new InputStreamReader(stato.getInputStream()));
    
    				esito = in.readLine(); //ECCO, E' QUI AD ASPETTARE UNA EVENTUALE 
    DISCONNESSIONE DEL CLIENT E NON SI ACCORGE DELLA PROPRIA
    
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    			System.out.print("DisconnessioneClient: ho letto "+esito);
    			if (esito.equals("quit"));
    			guiClient.mostraChiudi();
    			disconnetti = client.terminaChiamata;
    		}
    		try {
    			System.out.println("DisconnessioneClient stampa quit");
    			out = new PrintWriter(stato.getOutputStream());
    			out.write("quit");
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }
    Ho letto su altri forum che dovrei usare al posto della read una select() con un timeout ma non ho capito come fare...
    Qualcuno sa aiutarmi?? grazie mille!!

  2. #2
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    Ti consiglio, per i Thread, di implementare Runnable anziché utilizzare proprio una classe derivata da Thread: extends Thread si usa quando si vuole essere sicuri che la classe non estenda altre classi, se è questo il comportamento voluto allora ok. Se ti interessa invece poter derivare (o non escludere a priori questa opzione) usa implements Runnable.

    Suppongo che usi o variabili statiche o variabili non private violando le regole di encapsulation e me ne accorgo da qui

    codice:
    disconnetti = client.terminaChiamata;
    che poi non so che senso abbia visto che cmq mantieni un riferimento a client e potresti dedurre il valore ogni volta dal client (più corretto per evitare casini di mancato aggiornamento).

    codice:
    in = new BufferedReader(new InputStreamReader(stato.getInputStream()));
    
    				esito = in.readLine(); //ECCO, E' QUI AD ASPETTARE UNA EVENTUALE 
    DISCONNESSIONE DEL CLIENT E NON SI ACCORGE DELLA PROPRIA
    A parte che da qui non si sa se stato è stato inizializzato oppure no (so che esiste la variabile, ma dove la inizializzi? dove apri la connessione al server?).
    Usando socket e in particolare questa istruzione, tu apri uno stream in lettura "agganciandoti" (passatemi il termine) all'input stream del socket.
    Ora non so dove lo istanzi/usi, ma se non hai un server remoto a cui ti colleghi tramite socket e da cui invii il comando quit dubito che funzioni.
    Ci sarebbero altre note poco chiare su quello che fa il codice, ma per adesso sorvoliamo

    Infine di cosa non si accorge? Mica tu dal client puoi scrivere quit e lo ricevi tramite socket!!!

  3. #3
    Utente di HTML.it
    Registrato dal
    Oct 2010
    Messaggi
    13
    Originariamente inviato da valia
    Ti consiglio, per i Thread, di implementare Runnable anziché utilizzare proprio una classe derivata da Thread: extends Thread si usa quando si vuole essere sicuri che la classe non estenda altre classi, se è questo il comportamento voluto allora ok. Se ti interessa invece poter derivare (o non escludere a priori questa opzione) usa implements Runnable.

    Suppongo che usi o variabili statiche o variabili non private violando le regole di encapsulation e me ne accorgo da qui

    codice:
    disconnetti = client.terminaChiamata;
    Uso una variabile pubblica, ma non statica. L'utilizzo di quella variabile va bene, non è lì il problema perché il programma per il resto funziona perfettamente.

    che poi non so che senso abbia visto che cmq mantieni un riferimento a client e potresti dedurre il valore ogni volta dal client (più corretto per evitare casini di mancato aggiornamento).
    Il valore lo deduco ogni volta dal client perché ad ogni cliclo del while aggiorno il mio valore con il valore presente nel client.

    codice:
    in = new BufferedReader(new InputStreamReader(stato.getInputStream()));
    
    				esito = in.readLine(); //ECCO, E' QUI AD ASPETTARE UNA EVENTUALE 
    DISCONNESSIONE DEL CLIENT E NON SI ACCORGE DELLA PROPRIA
    A parte che da qui non si sa se stato è stato inizializzato oppure no (so che esiste la variabile, ma dove la inizializzi? dove apri la connessione al server?).
    Usando socket e in particolare questa istruzione, tu apri uno stream in lettura "agganciandoti" (passatemi il termine) all'input stream del socket.
    Ora non so dove lo istanzi/usi, ma se non hai un server remoto a cui ti colleghi tramite socket e da cui invii il comando quit dubito che funzioni.
    Ci sarebbero altre note poco chiare su quello che fa il codice, ma per adesso sorvoliamo
    E' tutto istanziato e connesso naturalmente, ma non potevo postare 20 pagine di codice. Gli altri messaggi viaggiano senza problemi, il mio unico problema è quella read.

    Infine di cosa non si accorge? Mica tu dal client puoi scrivere quit e lo ricevi tramite socket!!!
    Qui il thread aspetta che dall'altro lato il client gli dica se si è disconnesso o meno (se ricevo un evento "chiudi" invio un messaggio quit e poi chiudo) e non si accorge se la propria gui intanto ha aggiornato il valore "disconnetti", perché naturalmente si deve chiudere in entrambi i casi.

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    occhio che hai thread, quindi sono due "miniprocessi" separati che hanno un minimo di vita indipendente. Questo vuole dire che il thread può interrompersi dopo aver letto disconnetti, e riprendere in un'istante in cui dal client hai cambiato il valore di disconnetti, di fatto perdendo l'evento perché tu non rileggi disconnetti. Proprio per questo motivo devi stare molto attento a quel valore e passare il meno possibile per variabili d'appoggio (disconnetti locale appunto).

    La read si blocca perché da un lato hai la disconnessione e chiudi, ma dall'altro lato non ti accorgi o non gestisci bene il punto in cui ti trovi.

  5. #5

    Read non bloccante

    Se vuoi uno stream non bloccante devi utilizzare java nio.

  6. #6
    Utente di HTML.it
    Registrato dal
    Oct 2010
    Messaggi
    13

    Re: Read non bloccante

    Originariamente inviato da Devil01
    Se vuoi uno stream non bloccante devi utilizzare java nio.
    Sto tentando di risolvere utilizzando un ObjectInputStream e il metodo available()...

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    beh se ti ricordi bene
    codice:
    available
    
    public int available()
                  throws IOException
    Returns the number of bytes that can be read without blocking.
    Specified by:
    available in interface ObjectInput
    Overrides:
    available in class InputStream
    Returns:
    the number of available bytes.
    Throws:
    IOException - if there are I/O errors while reading from the underlying InputStream
    e usi l'eccezione per gestire un caso di disconnessione (logicamente sbagliato) può andare come soluzione (anche se secondo me devi rivedere un po' l'architettura)

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.