Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479

    Trasferimento file client-server

    Ciao a tutti!!!
    per fare trasferimento file da client a server ho scritto questo codice:

    UPLOADER
    codice:
    ObjectOutputStream out = new ObjectOutputStream( sock.getOutputStream() );
    System.out.println("Inizio esecuzione upload");
    FileInputStream fis = new FileInputStream(fileToUpload);
    
    byte[] dati = new byte[10000];
    int quanti = fis.read(dati);
    			
    while( quanti > 0 )
    {
    out.writeObject( new Messaggio( dati, quanti, Messaggio.FILE_DATA) );
    quanti = fis.read(dati);
    }
    DOWNLOADER
    codice:
    File file = new File( fileToDownload );
    FileOutputStream fos = new FileOutputStream( file );
    ObjectInputStream in = new ObjectInputStream( sock.getInputStream() );
    
    boolean stoScaricando = true;
    byte[] tmp;
    			
    while( stoScaricando )
    {
    	Messaggio letto = (Messaggio)in.readObject();
    				
    	switch( letto.getFlag() )
    	{
    		case Messaggio.FILE_DATA:
    		{
    			tmp = new byte[ letto.getQuanti() ];
    						
    			for (int j=0; j<tmp.length; j++) 
    				tmp[j] = letto.getData()[j];
    						
    			fos.write( tmp );
    			fos.flush();
    			break;
    		}
    					
    		case Messaggio.FINE_FILE_TRANSFER:
    		{
    			stoScaricando = false;
    			System.out.println("Fine trasferimento file.");
    			fos.close();
    			break;
    		}
    	}
    }
    Praticamente ottengo che il file viene trasferito per intero ma viene salvato dall'altra parte solo il primo blocco..ripetuto per l'intera lunghezza del messaggio. Nel caso di un mp3 si sentono i primi 10k di canzone ripetuti per l'intera durata della canzone

    Non riesco proprio a capire dove sia il problema...
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Il concetto di base che hai usato, cioè serializzare degli oggetti che rappresentano dei "messaggi" va bene ed è anche sicuramente comodo.

    Io però suggerirei di non fare una unica classe Messaggio, ma di fare una gerarchia di classi per i messaggi! Una classe astratta Messaggio e poi sottoclassi concrete come ad es. MessaggioInfoFile, MessaggioDatiFile, ecc....
    Nel ricevente basta leggere l'oggetto, fare dei test con instanceof e poi un cast. Niente flag o roba del genere. Ha anche più senso, visto che così si può "specializzare" meglio un tipo di messaggio con le proprietà peculiari del messaggio. Se devi solo indicare un fine trasferimento, perché dovresti creare un Messaggio che invece "sa" di avere anche un array di dati???

    Per il resto ... cose del tipo:
    codice:
    tmp = new byte[ letto.getQuanti() ];
    						
    for (int j=0; j<tmp.length; j++) 
        tmp[j] = letto.getData()[j];
    non hanno molto senso! Se il messaggio contiene un array, fatti restituire il reference all'array, il numero di byte e scrivi direttamente quello!

    Pure la lettura nel uploader si può fare in modo più furbo con:
    codice:
    int quanti;
    			
    while ((quanti = fis.read (dati)) > 0)
        out.writeObject (new Messaggio (dati, quanti, Messaggio.FILE_DATA));
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479
    Si ci avevo pensato a fare la gerarchia di classi ma non sapevo se potesse essere una buona idea, domani la modifico

    Per quanto riguarda il trasferimento ho modificato cosi':

    UPLOADER
    codice:
    byte[] dati = new byte[10000];	
    int quanti;
    			
    while ((quanti = fis.read (dati)) > 0)
        out.writeObject (new Messaggio (dati, quanti, Messaggio.FILE_DATA));		
    			
    out.close();
    DOWNLOADER
    codice:
    while( true )
    {
    	Messaggio letto = (Messaggio)in.readObject();
    
    	int quanti = letto.getQuanti();
    	byte[] tmp = new byte[quanti];
    	byte[] data = letto.getData();
    	tmp = data;
    	fos.write( tmp );
    	fos.flush();
    }
    ma ancora l'mp3 viene mandato sempre nello stesso modo, viene scritto il primo messaggio per tutta la durata della canzone. Ho notato anche che l'mp3 origunale e' 3.222 KB e quello inviato e' 3.223 KB
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Poker1
    ma ancora l'mp3 viene mandato sempre nello stesso modo, viene scritto il primo messaggio per tutta la durata della canzone. Ho notato anche che l'mp3 origunale e' 3.222 KB e quello inviato e' 3.223 KB
    Immagino che nella classe Messaggio assegni ad un campo interno l'array passato al costruttore. Cioè vuol dire sostanzialmente che durante il processo di serializzazione vengono serializzati tutti i 10000 byte dell'array. L'ultimo blocco potrebbe però contenere meno dati, ovviamente. Ma facendo fos.write( tmp ); tu scrivi tutti questi 10000 byte. Devi usare l'altro write() a cui indicare anche la lunghezza. O in alternativa quando crei un Messaggio, dovresti allocare un nuovo array di dimensione "giusta" per contenere i dati.

    Comunque non è il caso di fare:
    codice:
    byte[] tmp = new byte[quanti];
    byte[] data = letto.getData();
    tmp = data;
    letto.getData() ti ritorna l'array e devi scrivere direttamente quello!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479
    Ok ho risolto cosi':

    UPLOADER
    codice:
    byte[] dati = new byte[DIMENSIONE];	
    int quanti;
    			
    while((quanti = fis.read (dati)) > 0)
    {
        out.writeObject (new MessaggioDati( network.getMy(), 
    			    		                        fileToUpload.getName(),
    			    		                         dati,
    			    		                         quanti) );	
       dati = new byte[DIMENSIONE];
    }
    out.close();
    DOWNLOADER
    codice:
    while( (messaggioDati = (MessaggioDati) in.readObject()).quanti() > 0 )
    {
    	fos.write( messaggioDati.dati(), 0, messaggioDati.quanti() );
    	fos.flush();
    }
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

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.