[risolto][java] Error socket closed

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
minat09
Prode Principiante
Messaggi: 87
Iscrizione: domenica 12 maggio 2013, 11:32

[risolto][java] Error socket closed

Messaggio da minat09 »

Ho scritto un programma per lo scambio di messaggi tra client che comunicano attraverso un server.
Alla chiusura di un client viene segnalato l'errore "Socket closed" che, da come ho letto, indica che continua ad esserci una richiesta anche dopo la chiusura del socket.
Quello che ho notato però, è che l'errore si presenta solo usando un interrupt() mentre usando il metodo deprecato stop() non c'è nessun errore. Come posso modificare il codice?

Codice: Seleziona tutto

// metodo che rimuove il client
    public synchronized void remove(int ID){  
        // posizione del thread
        int pos = findClient(ID);
        if (pos >= 0){  
            ServerThread toTerminate = clients[pos];
            ui.TextArea1.append("\nRimozione client thread " + ID);
	    if (pos < clientCount-1){
                for (int i = pos+1; i < clientCount; i++){
                    clients[i-1] = clients[i];
	        }
	    }
	    clientCount--;
	    try{  
	      	toTerminate.close(); 
	    }
	    catch(IOException ioe){  
	      	ui.TextArea1.append("\nErrore nella chiusura del thread: " + ioe); 
	    }
	    toTerminate.stop();    //************ERRORE***************************************++
	}
    }

Codice: Seleziona tutto

// metodo che ricerca un client attraverso il suo ID
    private int findClient(int ID){  
    	for (int i = 0; i < clientCount; i++){
        	if (clients[i].getID() == ID){
                    // viene ritornata la posizione del thread nell'array
                    return i;
                }
	}
	return -1;
    }

Codice: Seleziona tutto

public void close() throws IOException {  
    	if (socket != null)    
            socket.close();
        if (streamIn != null)  
            streamIn.close();
        if (streamOut != null) 
            streamOut.close();
    }

Codice: Seleziona tutto

@Override
	public void run(){  
    	ui.TextArea1.append("\nServer Thread " + ID + " avviato.");
        while (true){  
    	    try{  
                Message msg = (Message) streamIn.readObject();
                System.out.println("Messaggio ricevuto"+msg.toString());
    	    	server.handle(ID, msg);
            }
            catch(IOException | ClassNotFoundException ioe){  
            	System.out.println(ID + " ERROR reading: " + ioe.getMessage());
                server.remove(ID);
                interrupt();
            }
        }
    }
Ultima modifica di minat09 il martedì 16 febbraio 2016, 13:26, modificato 1 volta in totale.
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1627
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [java] Error socket closed

Messaggio da nuzzopippo »

Il codice su esposto è parziale, quindi può essere una mia errata interpretazione, vedo che nel codice metodo "close()" chiudi prima il socket e poi i canali di input/output, se uno o entrambi tali canali sono stati ottenuti dal socket vanno chiusi prima di quest'ultimo, la pendenza dei canali di comunicazione a socket chiuso sarebbe ovvia altrimenti.
Fatti non foste a viver come bruti ...
minat09
Prode Principiante
Messaggi: 87
Iscrizione: domenica 12 maggio 2013, 11:32

Re: [java] Error socket closed

Messaggio da minat09 »

nuzzopippo [url=http://forum.ubuntu-it.org/viewtopic.php?p=4852848#p4852848][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Il codice su esposto è parziale, quindi può essere una mia errata interpretazione, vedo che nel codice metodo "close()" chiudi prima il socket e poi i canali di input/output, se uno o entrambi tali canali sono stati ottenuti dal socket vanno chiusi prima di quest'ultimo, la pendenza dei canali di comunicazione a socket chiuso sarebbe ovvia altrimenti.
Ho provato a cambiare l'ordine di chiusura ma non cambia nulla!
Posto le due classi SocketServer e SocketClient

Codice: Seleziona tutto

package fabchat;

import java.io.*;
import java.net.*;

class ServerThread extends Thread { 
	
    public SocketServer server = null;
    public Socket socket = null;
    // variabile che indica il numero del thread
    public int ID = -1;
    public String username = "";
    public ObjectInputStream streamIn  =  null;
    public ObjectOutputStream streamOut = null;
    public ServerGUI ui;

    public ServerThread(SocketServer _server, Socket _socket){  
    	super();
        server = _server;
        socket = _socket;
        ID     = socket.getPort();
        ui = _server.ui;
    }
    
    // metodo per l'invio di messaggi
    public void send(Message msg){
        try {
            streamOut.writeObject(msg);
            streamOut.flush();
        } 
        catch (IOException ex) {
            System.out.println("Exception [SocketClient : send(...)]"+ex);
        }
    }
    
    // ritorna l'id dell'utente, ovvero il numero del thread
    public int getID(){  
        return ID;
    }
   
    
    @Override
	public void run(){  
    	ui.TextArea1.append("\nServer Thread " + ID + " avviato.");
        while (true){  
    	    try{  
                Message msg = (Message) streamIn.readObject();
                System.out.println("Messaggio ricevuto"+msg.toString());
    	    	server.handle(ID, msg);
            }
            catch(IOException | ClassNotFoundException ioe){  
            	System.out.println(ID + " ERROR reading: " + ioe.getMessage());
                server.remove(ID);
                interrupt();
            }
        }
    }
    
    public void open() throws IOException {  
        streamOut = new ObjectOutputStream(socket.getOutputStream());
        streamOut.flush();
        streamIn = new ObjectInputStream(socket.getInputStream());
    }
    
    public void close() throws IOException {  
        if (streamIn != null)  
            streamIn.close();
        if (streamOut != null) 
            streamOut.close();
        if (socket != null)    
            socket.close();
    }
}


public class SocketServer implements Runnable {
    
    private ServerThread clients[]; // array di client
    public ServerSocket server = null;
    public Thread thread = null;
    public int clientCount = 0; 
    public int port = 13000; // imposto il numero di porta del server
    public ServerGUI ui;
    public Database db;

    public SocketServer(ServerGUI frame){
        // creo un array di 50 elementi
        clients = new ServerThread[50];
        ui = frame;
        db = new Database(ui.filePath);
        
	try{  
	    server = new ServerSocket(port);
            port = server.getLocalPort();
	    ui.TextArea1.append("Server partito.IP : " + InetAddress.getLocalHost() + ", Porta : " + server.getLocalPort());
	    avvia(); 
        }
	catch(IOException ioe){  
            ui.TextArea1.append("Impossibile usare la porta : " + port + "\nRetrying"); 
            ui.Riprova(0);
	}
    }
    
    public SocketServer(ServerGUI frame, int Port){
       
        clients = new ServerThread[50];
        ui = frame;
        port = Port;
        db = new Database(ui.filePath);
        
	try{  
	    server = new ServerSocket(port);
            port = server.getLocalPort();
	    ui.TextArea1.append("Server partito. IP : " + InetAddress.getLocalHost() + ", Porta : " + server.getLocalPort());
	    avvia(); 
        }
	catch(IOException ioe){  
            ui.TextArea1.append("\nImpossibile usare la porta " + port + ": " + ioe.getMessage()); 
	}
    }
	
    @Override
    public void run(){  
	while (thread != null){  
            try{  
		ui.TextArea1.append("\nIn attesa di un client ..."); 
	        addThread(server.accept()); 
	    }
	    catch(Exception ioe){ 
                ui.TextArea1.append("\nServer accept error: \n");
                ui.Riprova(0);
	    }
        }
    }
	
    private void avvia(){  
    	if (thread == null){  
            thread = new Thread(this); 
	    thread.start();
	}
    }
    
    // metodo invocato dal serverGUI per bloccare il thread
    public void stop(){  
        if (thread != null){  
            thread.interrupt(); 
	    thread = null;
	}
    }
    
    // metodo che ricerca un client attraverso il suo ID
    private int findClient(int ID){  
    	for (int i = 0; i < clientCount; i++){
        	if (clients[i].getID() == ID){
                    // viene ritornata la posizione del thread nell'array
                    return i;
                }
	}
	return -1;
    }
    
    
    public synchronized void handle(int ID, Message msg){  
        // ricevuta richiesta di disconnessione da parte di un utente
	if (msg.contenuto.equals(".bye")){
            clients[findClient(ID)].send(new Message(msg.tipo, msg.mitt, msg.contenuto, msg.dest));
            // comunico ai client che l'utente si sta scollegando
            Announce("logout", "SERVER", msg.mitt);
            // rimuovo l'utente
            remove(ID); 
	}
	else
        {
            switch (msg.tipo) {
                case "login":
                    if(findUserThread(msg.mitt) == null){
                        // controllo che i dati inseriti siano presenti nel database
                        if(db.checkLogin(msg.mitt, msg.contenuto,"login")){
                            clients[findClient(ID)].username = msg.mitt;
                            clients[findClient(ID)].send(new Message("login", "SERVER", "TRUE", msg.mitt));
                            
                            Announce("newuser", "SERVER", msg.mitt);
                            SendUserList(msg.mitt);
                            // avviso tutti i client che un nuovo utente  si è appena connesso
                            Announce("accesso",msg.mitt,msg.mitt);
                        }
                        else{
                            clients[findClient(ID)].send(new Message("login", "SERVER", "FALSE", msg.mitt));
                        }
                    }
                    else{
                        clients[findClient(ID)].send(new Message("login", "SERVER", "FALSE", msg.mitt));
                    }   break;
                case "message":
                    if(msg.dest.equals("Tutti")){
                        Announce("message", msg.mitt, msg.contenuto);
                    }
                    else{
                        findUserThread(msg.dest).send(new Message(msg.tipo, msg.mitt, msg.contenuto, msg.dest));
                        clients[findClient(ID)].send(new Message(msg.tipo, msg.mitt, msg.contenuto, msg.dest));
                    }   break;
                case "test":
                    clients[findClient(ID)].send(new Message("test", "SERVER", "OK", msg.mitt));
                    break;
                case "signup":
                    if(findUserThread(msg.mitt) == null){
                        if(!db.checkLogin(msg.mitt,"","signup")){
                            db.addUser(msg.mitt, msg.contenuto);
                            clients[findClient(ID)].username = msg.mitt;
                            clients[findClient(ID)].send(new Message("signup", "SERVER", "TRUE", msg.mitt));
                            clients[findClient(ID)].send(new Message("login", "SERVER", "TRUE", msg.mitt));
                            Announce("newuser", "SERVER", msg.mitt);
                            SendUserList(msg.mitt);
                            Announce("accesso",msg.mitt,msg.mitt);
                        }
                        else{
                            clients[findClient(ID)].send(new Message("signup", "SERVER", "FALSE", msg.mitt));
                        }
                    }
                    else{
                        clients[findClient(ID)].send(new Message("signup", "SERVER", "FALSE", msg.mitt));
                    }   break;
            }
	}
    }
    
    // metodo che comunica con tutti gli utenti connessi
    public void Announce(String tipo, String mitt, String contenuto){
        Message msg = new Message(tipo, mitt, contenuto, "Tutti");
            for(int i = 0; i < clientCount; i++)
            {
                clients[i].send(msg);
            }       
    }
    
    
    public void SendUserList(String toWhom){
        for(int i = 0; i < clientCount; i++){
            findUserThread(toWhom).send(new Message("newuser", "SERVER", clients[i].username, toWhom));
        }
    }
    
    private ServerThread findUserThread(String usr){
        for(int i = 0; i < clientCount; i++){
            if(clients[i].username.equals(usr)){
                return clients[i];
            }
        }
        return null;
    }
	
    // metodo che rimuove il client
    public synchronized void remove(int ID){  
        // posizione del thread
        int pos = findClient(ID);
        if (pos >= 0){  
            ServerThread toTerminate = clients[pos];
            ui.TextArea1.append("\nRimozione client thread " + ID);
	    if (pos < clientCount-1){
                for (int i = pos+1; i < clientCount; i++){
                    clients[i-1] = clients[i];
	        }
	    }
	    clientCount--;
	    try{  
	      	toTerminate.close(); 
	    }
	    catch(IOException ioe){  
	      	ui.TextArea1.append("\nErrore nella chiusura del thread: " + ioe); 
	    }
	    toTerminate.interrupt(); 
	}
    }
    
    private void addThread(Socket socket){  
	if (clientCount < clients.length){  
            ui.TextArea1.append("\nClient accettato: " + socket);
	    clients[clientCount] = new ServerThread(this, socket);
	    try{  
	      	clients[clientCount].open(); 
	        clients[clientCount].start();  
	        clientCount++; 
	    }
	    catch(IOException ioe){  
	      	ui.TextArea1.append("\nError opening thread: " + ioe); 
	    } 
	}
	else{
            ui.TextArea1.append("\nClient rifiutato: massimo numero di client connessi (" + clients.length + ") "
                    + "raggiunto.");
	}
    }  
    
}

Codice: Seleziona tutto

package fabchat;

import java.io.*;
import java.net.*;

public class SocketClient implements Runnable{
    
    public int port;  //porta del server
    public String serverAddr;   // indirizzo del server
    public Socket socket;
    public ClientGUI ui;
    public ObjectInputStream In;
    public ObjectOutputStream Out;
    
    public SocketClient(ClientGUI frame) throws IOException{
        ui = frame; 
        this.serverAddr = ui.serverAddr; 
        this.port = ui.port;
        // creo nuova socket passandogli indirizzo del server e porta
        socket = new Socket(InetAddress.getByName(serverAddr), port);           
        Out = new ObjectOutputStream(socket.getOutputStream());
        Out.flush();
        In = new ObjectInputStream(socket.getInputStream());

    }

    @Override
    public void run() {
        boolean keepRunning = true;

        while(keepRunning){
            try {
                
                Message msg = (Message) In.readObject();   
                // stampo il messaggio in arrivo
                System.out.println("Incoming : "+msg.toString());
                
                
                switch (msg.tipo) {
                    case "message": // c'è uno scambio di messaggi tra due utenti
                        if(msg.dest.equals(ui.username)){
                            ui.jTextArea1.append("["+msg.mitt +" > Me] : " + msg.contenuto + "\n");
                        }
                        else{
                            ui.jTextArea1.append("["+ msg.mitt +" > "+ msg.dest +"] : " + msg.contenuto + "\n");
                        }   break;
                    case "login": // richiesta di autenticazione da un utente
                        // se i dati di accesso esistono, allora viene restituito "true" e cambio il valore dei bottoni
                        if(msg.contenuto.equals("TRUE")){
                            ui.jButton3.setEnabled(false);
                            ui.jButton4.setEnabled(true);
                            ui.jTextArea1.append("[SERVER > Me] : Accesso effettuato\n");
                            ui.jTextField3.setEnabled(false);
                            ui.jPasswordField1.setEnabled(false);
                            // aggiungo un valore alla lista degli utenti connessi
                            ui.model.addElement("Tutti");
                            // cambio il testo del bottone da "login" a "logout"
                            ui.jButton2.setText("Logout");
                        }
                        else{
                            // dati di accesso non trovati nel database
                            ui.jTextArea1.append("[SERVER > "+msg.dest+"] : Accesso negato\n");
                        }   break;
                    case "accesso":
                        // messaggio a tutti gli utenti connessi
                        ui.jTextArea1.append("[SERVER > Tutti] : L'utente "+msg.contenuto+" si è connesso\n");
                        break;
                    case "test": // connessione al server
                        ui.jButton1.setEnabled(false);
                        ui.jButton2.setEnabled(true);
                        ui.jButton3.setEnabled(true);
                        ui.jTextField3.setEnabled(true);
                        ui.jPasswordField1.setEnabled(true);
                        ui.jTextField1.setEditable(false);
                        ui.jTextField2.setEditable(false);
                        ui.jTextArea1.append("[SERVER > Me] : Connessione al server stabilita\n");
                        break;
                    case "newuser": // se non è già presente, aggiungo un username alla lista degli utenti connessi
                        if(!msg.contenuto.equals(ui.username)){
                            boolean exists = false;
                            for(int i = 0; i < ui.model.getSize(); i++){
                                if(ui.model.getElementAt(i).equals(msg.contenuto)){
                                    exists = true; 
                                    break;
                                }
                            }
                            if(!exists)
                            { 
                                ui.model.addElement(msg.contenuto); 
                            }
                        }   break;
                    case "signup": // registrazione di un nuovo utente
                        // se non è già presente un utente con lo stesso username, procedo con la registrazione
                        if(msg.contenuto.equals("TRUE")){
                            ui.jButton2.setText("Logout");
                            ui.jButton3.setEnabled(false);
                            ui.jButton4.setEnabled(true);
                            ui.jTextArea1.append("[SERVER > Me] : Registrazioni eseguita\n");
                        }
                        else{
                            ui.jTextArea1.append("[SERVER > Me] : Registrazione fallita\n");
                        }   break;
                    case "signout": // utente scollegato
                            ui.jTextArea1.append("["+ msg.mitt +" > Me] : Disconnesso..\n");
                            ui.jButton1.setEnabled(true);
                            ui.jButton2.setEnabled(false);
                            ui.jButton4.setEnabled(false);
                            ui.jTextField1.setEditable(true);
                            ui.jTextField2.setEditable(true);
                            ui.jTextField3.setEditable(true);
                            ui.jPasswordField1.setEditable(true);
                            // rimuovo tutti gli utenti online dalla lista dell'utente che si è appena scollegato
                            ui.model.removeAllElements();
                            // blocco il thread
                            ui.clientThread.interrupt();
                            // blocco il ciclo while
                            keepRunning = false;
                            break;
                    case "logout":
                            // avviso tutti gli utenti che l'utente x si è disconnesso
                            ui.jTextArea1.append("[SERVER > Tutti] : L'utente "+msg.contenuto+" si è disconnesso\n");
                            for(int i = 1; i < ui.model.size(); i++){
                                // rimuovo l'utente disconnesso dalla lista degli utenti connessi
                                ui.model.removeElement(msg.contenuto);
                            } 
                        break;
                    default:
                        ui.jTextArea1.append("[SERVER > Me] : Tipo di messaggio sconosciuto\n");
                        break;
                }
            }
            catch(IOException | ClassNotFoundException ex) {
                // blocco il ciclo while
                keepRunning = false;
                ui.jTextArea1.append("[Application > Me] : Connessione al server fallita\n");
                ui.jButton1.setEnabled(true); 
                ui.jTextField1.setEditable(true); 
                ui.jTextField2.setEditable(true);
                ui.jButton4.setEnabled(false);
                
                for(int i = 1; i < ui.model.size(); i++){
                    ui.model.removeElementAt(i);
                }
                // blocco il thread
                ui.clientThread.interrupt();
                
                System.out.println("Exception SocketClient run()"+ex);
            }
        }
    }
    
    // metodo invocato dal clientGUI per l'invio di messaggi
    public void send(Message msg){
        try {
            Out.writeObject(msg);
            Out.flush();
            System.out.println("Outgoing : "+msg.toString());       
        } 
        catch (IOException ex) {
            System.out.println("Exception SocketClient send()"+ex);
        }
    }
    
    public void closeThread(Thread t){
        t = null;
    }
}
minat09
Prode Principiante
Messaggi: 87
Iscrizione: domenica 12 maggio 2013, 11:32

Re: [java] Error socket closed

Messaggio da minat09 »

up
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1627
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [java] Error socket closed

Messaggio da nuzzopippo »

Allora, non ho ancora visto bene il Tuo codice, per questioni di tempo che non mi permettono di stendere un test basato su di esso, sono però andato a rivedermi un po' i libri e la documentazione relativa a thread e socket prima di dire qualche corbelleria.

In merito al thread segnalo che la istruzione "thread.interrupt()" viene indicata da utilizzarsi per l'interruzione di thread bloccati e genera una eccezione, un modo suggerito per interrompere un thread è l'inserimento di un flag nel metodo "run()" del thread che permetta di uscire dal ciclo di funzionamento, a mero di esempio vedi questa slide universitaria pagine 42 e 37 rispettivamente per le indicazioni su.

Più articolata e da studiarsi è la gestione del socket, in questo caso la mia fonte è il testo "Core Java 2" vol II° ed. Java 5 ove, a pag. 181 trovo l'argomento "socket interrompibili" che indica l'utilizzo dei "SocketChannel" per implementare una interruzione interattiva dei socket (con diverse pagine di esempio) gestendo eventuali pendenze di dati ... non penso che tale metodologia sia idonea alla chat che stai realizzando.
Probabilmente il problema segnalato è dovuto alla continuazione del ciclo nel run() del thread in pendenza del la chiusura del socket.

Prendimi con le molle, non sono una cima, ma allo stato suggerirei, quale tentativo, di inserire un flag di controllo nella definizione del thread, trasformare il Tuo metodo close() in modo che valorizzi opportunamente detta variabile e quindi modificare le istruzioni del metodo "run()" del thread ... una cosa del genere in sostanza

Codice: Seleziona tutto

class ServerThread extends Thread {
   
    public SocketServer server = null;
    public Socket socket = null;
    // variabile che indica il numero del thread
    public int ID = -1;
    public String username = "";
    public ObjectInputStream streamIn  =  null;
    public ObjectOutputStream streamOut = null;
    public ServerGUI ui;
    private boolean continua = true;

...
    public void close() throws IOException { 
        continua = false;
        if (streamIn != null) 
            streamIn.close();
        if (streamOut != null)
            streamOut.close();
        if (socket != null)   
            socket.close();
    }
...
    @Override
   public void run(){ 
       ui.TextArea1.append("\nServer Thread " + ID + " avviato.");
        while (continua){ 
           try{ 
                Message msg = (Message) streamIn.readObject();
                System.out.println("Messaggio ricevuto"+msg.toString());
              server.handle(ID, msg);
            }
            catch(IOException | ClassNotFoundException ioe){ 
               System.out.println(ID + " ERROR reading: " + ioe.getMessage());
                server.remove(ID);
                interrupt();
            }
        }
        
    }
Ciò credo eviterebbe al thread di avviare un ciclo di lettura dati dal socket a socket chiuso, non ho ancora ben presenti tutte le interazioni del Tuo codice (maledetto tempo) ma penso probabile che sia quello il motivo scatenante del problema. Fai sapere, ciao.

[Edit] ovviamente, sarebbe da valutarsi la serie di istruzioni "interrut()" che ho visto sparse nel codice, in particolare la calibrazione tra metodo "stop()" e l'istruzione "toTerminate.close()" del metodo "remove(int ID)" nel server
Fatti non foste a viver come bruti ...
minat09
Prode Principiante
Messaggi: 87
Iscrizione: domenica 12 maggio 2013, 11:32

Re: [java] Error socket closed

Messaggio da minat09 »

nuzzopippo [url=http://forum.ubuntu-it.org/viewtopic.php?p=4853373#p4853373][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Allora, non ho ancora visto bene il Tuo codice, per questioni di tempo che non mi permettono di stendere un test basato su di esso, sono però andato a rivedermi un po' i libri e la documentazione relativa a thread e socket prima di dire qualche corbelleria.

In merito al thread segnalo che la istruzione "thread.interrupt()" viene indicata da utilizzarsi per l'interruzione di thread bloccati e genera una eccezione, un modo suggerito per interrompere un thread è l'inserimento di un flag nel metodo "run()" del thread che permetta di uscire dal ciclo di funzionamento, a mero di esempio vedi questa slide universitaria pagine 42 e 37 rispettivamente per le indicazioni su.

Più articolata e da studiarsi è la gestione del socket, in questo caso la mia fonte è il testo "Core Java 2" vol II° ed. Java 5 ove, a pag. 181 trovo l'argomento "socket interrompibili" che indica l'utilizzo dei "SocketChannel" per implementare una interruzione interattiva dei socket (con diverse pagine di esempio) gestendo eventuali pendenze di dati ... non penso che tale metodologia sia idonea alla chat che stai realizzando.
Probabilmente il problema segnalato è dovuto alla continuazione del ciclo nel run() del thread in pendenza del la chiusura del socket.

Prendimi con le molle, non sono una cima, ma allo stato suggerirei, quale tentativo, di inserire un flag di controllo nella definizione del thread, trasformare il Tuo metodo close() in modo che valorizzi opportunamente detta variabile e quindi modificare le istruzioni del metodo "run()" del thread ... una cosa del genere in sostanza

Codice: Seleziona tutto

class ServerThread extends Thread {
   
    public SocketServer server = null;
    public Socket socket = null;
    // variabile che indica il numero del thread
    public int ID = -1;
    public String username = "";
    public ObjectInputStream streamIn  =  null;
    public ObjectOutputStream streamOut = null;
    public ServerGUI ui;
    private boolean continua = true;

...
    public void close() throws IOException { 
        continua = false;
        if (streamIn != null) 
            streamIn.close();
        if (streamOut != null)
            streamOut.close();
        if (socket != null)   
            socket.close();
    }
...
    @Override
   public void run(){ 
       ui.TextArea1.append("\nServer Thread " + ID + " avviato.");
        while (continua){ 
           try{ 
                Message msg = (Message) streamIn.readObject();
                System.out.println("Messaggio ricevuto"+msg.toString());
              server.handle(ID, msg);
            }
            catch(IOException | ClassNotFoundException ioe){ 
               System.out.println(ID + " ERROR reading: " + ioe.getMessage());
                server.remove(ID);
                interrupt();
            }
        }
        
    }
Ciò credo eviterebbe al thread di avviare un ciclo di lettura dati dal socket a socket chiuso, non ho ancora ben presenti tutte le interazioni del Tuo codice (maledetto tempo) ma penso probabile che sia quello il motivo scatenante del problema. Fai sapere, ciao.

[Edit] ovviamente, sarebbe da valutarsi la serie di istruzioni "interrut()" che ho visto sparse nel codice, in particolare la calibrazione tra metodo "stop()" e l'istruzione "toTerminate.close()" del metodo "remove(int ID)" nel server
Intanto ti ringrazio per il tuo tempo. Avevo giá provato proprio questa soluzione ma cambiavo il valore della variabile nel metodo remove() dove c'è anche l'interrupt,sbagliando quindi. Cambiando il valore prima della chiusura dei canali non ho più nessun errore!!grazie!!
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 20 ospiti