Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    11

    Socket e canali input/output

    Salve, ho un problema nell'implementazione di un applicazione client-server, in sostanza ho creato 3 classi:
    - Canale: è una classe a che ha come attributi un oggetto Socket e BufferedReader e BufferedWriter, nel costruttore assegno il socket in ingresso all'attributo Socket;

    successivamente ho implementato il metodo per aprire i canali, in realtà assegna ai miei due attributi il references dei canali che sono stati associati al socket, nel seguente modo:
    codice:
    BufferedReader in=new BufferedReader(new InputStream(socket.getInputStream()));
    BufferedWriter out=new BufferedWriter (new OutputStream(socket.getOutputStream()));
    e quello per chiuderli.
    Inoltre i metodi write e read che servono per scrivere e leggere sul canale richiamando i metodi delle classi BufferedReader e BufferedWriter.
    Il client riesce a connettersi al server ma funziona sole se dopo aver scritto o letto chiudo i canali con i metodi in.close() e out.close(), così l'applicazione server riesce a scrivere una stringa e quella client riesce a leggere, se non chiudo i canali rimane incantato. Successivamente a queste istruzioni ho inserito altre scritture e letture che non avvengono.
    Il mio problema è che:
    -se chiudo i canali ho scoperto che viene chiuso anche il socket, quindi una successiva apertura dei canali da parte del server andrebbe in fallimento.
    -se non chiudo i canali non viene effettuata neanche la prima lettura da parte del client.

    Ecco dovrei trovare un modo per mantenere aperti i canali per tutto il tempo di esecuzione delle applicazioni, durante il quale devo continuare a inviare e ricevere messaggi da parte di tutti e due gli host, pensavo che bastasse la flush() per forzare la vuotatura del canale e quindi dare la possibilità al client di effettuare una read, ma ciò non funziona se non richiamo la close() sui canali!
    Grazie in anticipo

  2. #2

    Re: Socket e canali input/output

    Ovviamente stai gestendo le connessioni con dei thread vero? Posta il codice, hai postato due misere righe.
    Il centro dell'attenzione non è sempre un buon posto in cui trovarsi

    Mai discutere con uno stupido, la gente potrebbe non capire la differenza. (O. W.)

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    11
    OOOk....
    Allora classe myThread:
    codice:
     import java.net.*;
     import java.io.*;
    
     public class myThread extends Thread {
    	//ATTRIBUTI
    		//Variabile socket per assegnarlo al processo.
    			private Socket sok;
    		//Variabili per i canali di input e output.
    			private BufferedReader in;
    			private BufferedWriter out;
    		//Variabile flag per stampe d'errore.
    			private boolean control=true;
    			
    	//METODO COSTRUTTORE con assegnazione del socket al processo.
        	
    	    	public myThread(Socket sokcet) {
    	    		try{
    	    			this.setSocket(sokcet);
    	    				if(control)
    	    					System.out.println("Il SOCKET è stato assegnato al processo.");
    	    		}catch(Exception e){
        				if(control)
        					System.out.println("ERR Il SOCKET non è stato assegnato al processo.");
    	    		}
    	    	}
        
        	//Metodi per l'apertura dei canali.
        		public void openInBus(){
    				try{
    					in=new BufferedReader(new InputStreamReader(getSocket().getInputStream()));
    						if(control)
    							System.out.println("Il canale IN del processo è stato APERTO.");
    				}catch(Exception e){
    					if(control)
        					System.out.println("ERR Il canale IN del processo non è stato APERTO.");
    				}
        		}    	
        		public void openOutBus(){
    				try{
        				out=new BufferedWriter(new OutputStreamWriter(getSocket().getOutputStream()));
        					if(control)
    							System.out.println("Il canale OUT del processo è stato APERTO.");
    				}catch(Exception e){
    					if(control)
    						System.out.println("ERR Il canale OUT del processo non è stato APERTO.");
    				}
        		}    	
        	//Metodi per la chiusura dei canali.
        		public void closeInBus(){
    				try{
    					in.close();
    						if(control)
    							System.out.println("Il canale IN del processo è stato CHIUSO.");
    				}catch(Exception e){
    					if(control)
        					System.out.println("ERR Il canale IN del processo non è stato CHIUSO.");
    				}
        		}
        		public void closeOutBus(){
    				try{
        				out.close();
        					if(control)
        						System.out.println("Il canale OUT del processo è stato CHIUSO.");
    				}catch(Exception e){
    					if(control)
        					System.out.println("ERR Il canale OUT del processo non è stato CHIUSO.");
    				}
        		}
        //METODI TRASMISSIONE
        	//Metodo per scrivere sul canale.
        		public void write(String mex){
        			try{
                                    openOutBus(); //Apro il canale per scrivere
        				out.write(mex);
        				out.flush();
                                    closeOutBus(); //Chiudo il canale senno si impalla sulla readLine()
        					if(control)
        						System.out.println("SCRITTO sul canale.");
        			}catch(Exception e){
        				if(control)
    						System.out.println("ERR non SCRITTO sul canale.");
        			}
        		}
        	//Metodo per leggere sul canale.
        		public String read(){
        			String mex=null;
        			try{ 		
                                    openInBus();
        				mex=in.readLine();
                                    closeInBus(); //Chiudo il canale senno si impalla sulla readLine()
        					if(control)
        						System.out.println("LETTO sul canale.");
        			}catch(Exception e){
        				if(control)
    						System.out.println("ERR non LETTO sul canale.");
        			}
        			return mex;
        		}
        //METODO RUNNABLE
    		     public void run(){     	
    		     }
    Poi c'è la classe client:

    codice:
    import java.net.*;
    
    public class Client {
    	//ATTRIBUTI.
    		//Oggetto Socket per client.
    			private Socket client;
    		//Processo per assegnare il client.
    			private myThread taskClient;
    		//Variabile flag per stampe d'errore.
    			private boolean control=true;
    			
    	//METODO COSTRUTTORE
    		/*Effettua la connessione al server e assegna il client al processo.*/
    			
    			public Client(String ipServer, int port) {
    				try {
    					client=new Socket(ipServer,port);
    						if(control)
    							System.out.println("Il SOCKET CLIENT si è connesso al server.");
    				}catch (Exception e) {
    					if(control)
    						System.out.println("ERR Il SOCKET CLIENT non si è connesso al server.");
    				}
    				taskClient=new myThread(client);
    				taskClient.start();
    			}
    	//METODI CLASSE
    		//METODO SCRIVI sul canale.
    			public void write(String mex){
    				try{
    					taskClient.write(mex);
    						if(control)
    							System.out.println("Il socket client ha SCRITTO sul canale.");
    				}catch(Exception e){
    					if(control)
    						System.out.println("ERR Il socket client non ha SCRITTO sul canale..");
    				}
    			}
    		//METODO LEGGI sul canale.
    			public String read(){		
    				String mex="";
    					try{		
    						mex=taskClient.read();
    							if(control)
    								System.out.println("Il socket client ha LETTO sul canale.");
    					}catch(Exception e){
    						if(control)
    							System.out.println("ERR Il socket client non ha LETTO sul canale..");
    					}
    				return mex;
    			}
    e quella server

    codice:
    import java.io.*;
    import java.net.*;
    
    public class Server extends Thread{
    	//ATTRIBUTI
    		//OggettoServerSocket.
    			private ServerSocket server;
    		//Array di 5 Oggetti 'myThread'			che simulano i processi per ogni client connesso.
    			private myThread clients[];
    		//Indice utile per l'array di clients.
    			private int index;
    		//Variabile flag per stampe d'errore.
    			private boolean control=true;
    			
    	//METODO COSTRUTTORE
    		/*Mette in ascolto il server sulla porta 'port'
    		Assegna il server ad un processo in modo da
    		tenerlo indipendente dai processi dei clients*/
    			
    			public Server(int port){
    				//Connessione alla porta.
    				try {
    					server = new ServerSocket(port);	
    						if(control)
    							System.out.println("Il SERVER si è connesso alla porta.");
    				} catch (Exception e) {		
    					if(control)
    						System.out.println("ERR Il SERVER non si è connesso alla porta.");
    				}
    				//Creazione 5 processi per socket.
    				clients=new myThread[5];
    				//Assegnazione server al processo.
    				super.start();
    				setIndex(0);
    			}
    	//METODI CLASSE
    		//METODO GET e SET INDEX
    			private void setIndex(int index) {
    				this.index = index;
    			}
    			public int getIndex() {
    				return index;
    			}
    		//METODO CONNESSIONE.
    			public boolean connection(){
    				Socket sTemp;
    					while(index<1){
    						try {
    							if(control)
    								System.out.println("Il SERVER è in ascolto sulla porta....");
    								sTemp=server.accept();
    									if(control)
    										System.out.println("Il SERVER ha accettato un client");
    							clients[index]=new myThread(sTemp);
    							clients[index].start();
    							index++;							
    						}catch (IOException e) {
    							if(control)
    								System.out.println("ERR Il SERVER non ha accettato un client.");
    							return false;
    						}
    					}
    					if(control)
    						System.out.println("Il SERVER ha accettato il numero massimo di clients");
    				return true;
    			}
    		//METODO SCRIVI sul canale ad un determinato client.
    			public void write(String mex, int index){
    				try{
    					clients[index].write(mex);
    						if(control)
    							System.out.println("Il SERVER ha SCRITTO al client n"+index);
    				}catch(Exception e){
    					if(control)
    						System.out.println("ERR Il SERVER non ha SCRITTO al client n"+index);
    				}
    			}
    		//METODO SCRIVI sul canale a tutti i client.
    			public void write(String mex){
    				try{
    					write(mex,0);
    					write(mex,1);
    					write(mex,2);
    					write(mex,3);
    					write(mex,4);
    						if(control)
    							System.out.println("Il SERVER ha SCRITTO a tutti i clients.");
    				}catch(Exception e){
    					if(control)
    						System.out.println("ERR Il SERVER non ha SCRITTO a tutti il clients.");
    				}
    			}
    		//METODO LEGGI dal canale di un determinato client.
    			public String read(int index){
    				String mex="";
    					try{		
    						mex=clients[index].read();
    							if(control)
    								System.out.println("Il SERVER ha LETTO dal client n"+index);
    					}catch(Exception e){
    						if(control)
    							System.out.println("ERR Il SERVER non ha LETTO dal client n"+index);
    					}
    				return mex;
    			}
    		//METODO RUNNABLE.
    			public void run(){
    			}

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    11
    In questo modo scrive solo la prima volta, perchè chiudendo i canali si chiudono anche i socket, ma se io tolgo le close() dei canali e lo facessi alla fine di tutta la comunicazione, non effettua nemmeno la prima readLine(); wat's the problem, cioè l'ho capito il problema come risolverlo? Come non far chiudere i socket oppure come leggere dal canale senza che sia stato chiuso dopo la scrittura?

  5. #5
    Originariamente inviato da Kapuz92
    In questo modo scrive solo la prima volta, perchè chiudendo i canali si chiudono anche i socket, ma se io tolgo le close() dei canali e lo facessi alla fine di tutta la comunicazione, non effettua nemmeno la prima readLine(); wat's the problem, cioè l'ho capito il problema come risolverlo? Come non far chiudere i socket oppure come leggere dal canale senza che sia stato chiuso dopo la scrittura?
    Sto cercando di capire come hai impostato il codice ma fatico un po, posta anche il codice in cui fai uso di queste classi, la tua main. Quei metodi run vuoti mi perplimono assai. Cmq posta un po anche il resto del codice che magari capisco come vuoi impostare le cose.
    Il centro dell'attenzione non è sempre un buon posto in cui trovarsi

    Mai discutere con uno stupido, la gente potrebbe non capire la differenza. (O. W.)

  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    11
    Il resto del codice non l'ho ancora scritto...ma è una semplice sequenza in cui il server invia un messaggio il client lo legge e ne invia uno di risposta e così via...
    Esempio
    server
    codice:
    Server s=new Server(2222);
    s.connection();
    int n=0;
    
    s.write("Benvenuto");
    while(true){
    String t=s.read();
       try{
          n=Integer.parseInt(t);
       }catch(Exception e){
       }
          if(n==0)break;
          else
             s.write("Il numero è "+(n*n));
    }
    Esempio client
    codice:
    Client c=new Client("localhost",2222);
    
    System.out.println(c.read());
    
    while(true){
       String t=JOptionPane.showInputDialog(null,"Inserire il numero");
    
    }

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    11
    Il resto del codice non l'ho ancora scritto...ma è una semplice sequenza in cui il server invia un messaggio il client lo legge e ne invia uno di risposta e così via...
    Esempio
    server
    codice:
    Server s=new Server(2222);
    s.connection();
    int n=0;
    
    s.write("Benvenuto");
    while(true){
    String t=s.read();
       try{
          n=Integer.parseInt(t);
       }catch(Exception e){
       }
          if(n==0)break;
          else
             s.write("Il numero è "+(n*n));
    }
    Esempio client
    codice:
    Client c=new Client("localhost",2222);
    
    System.out.println(c.read());
    int n=0;
    while(true){
       String t=JOptionPane.showInputDialog(null,"Inserire il numero");
       try{
           n=Integer.parseInt(t);
           c.write(t);
        }catch(Exception e){
        }
           if(n==0)
              break;
    }
    L'ho inventato al momento, in realtà il codice sarà molto più complesso ad ogni invio di messaggio ci saranno molti più controlli e praticamente devo effettuare solo invio di messaggi per effettuare in base ad essi delle determinate operazioni nell'altro host...cmq in sostanza è un continuo e alterno scrivi e leggi tra server e client(in realta con piu client, ovvero:
    Server scrive client1
    Client1 risponde
    Server scrive client2
    Client2 risponde
    Server scrive client3
    Client3 risponde
    Server scrive client4
    Client4 risponde
    Server scrive client5
    Client5 risponde

    e poi di nuovo sarà:

    Server scrive client1
    Client1 risponde
    Server scrive client2
    Client2 risponde
    Server scrive client3
    Client3 risponde
    Server scrive client4
    Client4 risponde
    Server scrive client5
    Client5 risponde

    Comunque sia il problema l'ho trovato è che se chiudo i canali chiudo anche il socket, cosa che non deve accadere, ma se non chiudo i canali non riesco a leggere.

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.