Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    Invio file Client Server

    Devo inviare un file audio dal server al client e per fare questo invio inizialmente la dimensione del file al client in modo tale che con un ciclo while leggo i dati dalla socket e controllo anche che, quelli letti non superano la dimensione del file da ricevere, tutto questo perchè avevo dei problemi nel client che non interrompeva la lettura dalla socket con un semplice controllo sul valore restituito dalla read. Accade però che A VOLTE il client riceva come dimensione del file da leggere un valore negativo del tipo -1445667230 o molto grandi tipo 5856129044331985247 a cosa può essere dovuto? La dimensione inviata è corretta ma viene ricevuto un valore diverso.

    Nel Server

    codice:
    long dim_file = 0;
    int pos = 0;
    
    dim_file = file_da_inviare.getDimensione();
    output.writeLong(dim_file);
     while((pos=fis.read(buffer))!=-1){
              outd.write(buffer, 0, pos);
            }  
    
    output.flush();
    fis.close();
    Nel Client

    codice:
    long dimensione = 0;
    int pos = 0;
    int aggiungi = 0;
    
    dimensione = input.readLong();
    while(aggiungi <= dimensione){
                pos = input.read(buffer);
                aggiungi = aggiungi + pos;
                fos.write(buffer, 0, pos);
                if(aggiungi == dim){
                    aggiungi =0;
                    break;
        }
    fos.flush();
    fos.close();
    Succede che il programma funzioni regolarmente per due tre invi consecutivi e poi darmi come dimensione del file da ricevere un valore molto grande, oppure puo capitare che al primo tentativo o quello successivo mi viene restituito un valore negativo
    Non chiudo la socket perchè dovrei poter fare altre operazioni come ad esempio ricevere altri file.

    HELP ME PLEASE.....THANKS

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Io ho solo notato questa cosa qua che mi lascia perplesso:

    codice:
    output.writeLong(dim_file);
     while((pos=fis.read(buffer))!=-1){
              outd.write(buffer, 0, pos);
            }
    Mentre poi nel client leggi dallo stesso oggetto "input".

    Hai 2 oggetti che usano lo stesso canale di output (quello della socket)? Se è così, cambia strategia: l'uno potrebbe sporcare l'altro. Non si dovrebbero mai costruire 2 oggetti distinti sullo stesso canale.


    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
    Quello è stato un errore di distrazione nel riportare la porzione di codice nel post in effetti il codice è questo:

    codice:
    output.writeLong(dim_file);
     while((pos=fis.read(buffer))!=-1){
             output.write(buffer, 0, pos);
            }
    Io comunque sulla socket dovrei scrivere varie informazioni in questo caso solo i byte del file ma poi sia nel server che nel client alla socket ho associato diversi stream...

    Mi potresti dare una mano non capisco perchè l'errore capita casualmente, credevo fosse dovuto a overflow per i valori della dimensione dei file, ma come faccio ad esempio ad liberare la socket in qualke modo ad ogni scrittura solo con fflush().
    Non posso postare tutto il codice perchè fa parte di un progetto più ampio, dove come ho detto in precedenza ci sono fari stream associati alla socket. Secondo te dove potrebbe essere il problema cosa dovrei controllare dammi una mano per piacere.

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Io non ho mai riscontrato problemi di questo tipo nel trasferimento di file (di qualunque tipo) tra client e server. Il valore negativo mi fa pensare ad un file di dimensioni enormi (un long, usato per gestire la dimensione del file, arriva tranquillamente a 9.223.372.036.854.775.807 byte), ma non credo possa essere questo il caso.

    Di solito, però, gestisco il trasferimento in modo diverso: mi creo un protocollo di comunicazione e gestisco il trasferimento usando ObjectOutputStream e ObjectInputStream (ma non è questo a creare problemi).

    Una cosa che, sicuramente, puoi aggiungere al tuo codice è il flush dei dati.

    codice:
    output.writeLong( dimFile );
    output.flush();
    ...
    output.write(buffer, 0, pos);
    output.flush();
    Altra cosa che mi manca da capire è di che tipo siano l'oggetto "output" ed il corrispondente "input" sul client.


    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
    Server

    codice:
    private DataOutputStream output = null;
    output = new DataOutputStream(socket_client.getOutputStream());
    Client

    codice:
     private DataInputStream input = null;
     input = new DataInputStream(sock.getInputStream());
    Non riesco a trovare il prpblema se hai bisogno di altre informazioni chiedi pure, io cerco di guardarmi il codice per vedere dove possa esserci qualke problema....GRAZIE

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Prova, temporaneamente, ad usare questo codice.

    Lato server:
    codice:
    DataOutputStream output = null;
    FileInputStream fis = null;
    byte[] buffer = new byte[4096];   // Invio max 4 KB alla volta
    int byteLetti = 0;
    
    try {
       output = new DataOutputStream( socket.getOutputStream() );
       File f = new File( ... );   // Il tuo file da inviare
       output.writeLong( f.getLength() );
       output.flush();
       fis = new FileInputStream( f );
       while((byteLetti = fis.read(buffer)) >= 0) {
          output.write(buffer, 0, byteLetti);
          output.flush();
       }
    } catch (Exception e) {
       e.printStackTrace();
    } finally {
       if (output != null) {
          try { output.close(); } catch (Exception e) { }
       }
       if (fis != null) {
          try { fis.close(); } catch (Exception e) { }
       }
    }
    Lato client:
    codice:
    DataInputStream input = null;
    FileOutputStream fos = null;
    byte[] buffer = new byte[4096];   // Ricevo max 4 KB alla volta
    int byteLetti = 0; 
    long fileLength = 0;
    long crtlFileLength = 0;
    boolean error = false;
    try {
       input = new DataInputStream( socket.getInputStream() );
       fos = new FileOutputStream( ... );   // Il tuo file di output (ricevuto dal server)
       fileLength = input.readLong();
       while((ctrlFileLength < fileLength) && !error) {
          byteLetti = input.read(buffer);
          if (byteLetti >= 0) {
             fos.write(buffer, 0, byteLetti);
             fos.flush();
             ctrlFileLength += byteLetti;
          } else {
             error = true;
          }
       }
    
       if ( error ) System.out.println("Riscontrato errore in ricezione file");
    } catch (Exception e) {
       e.printStackTrace();
    } finally {
       if (input != null) {
          try { input.close(); } catch (Exception e) { }
       }
       if (fos != null) {
          try { fos.close(); } catch (Exception e) { }
       }
    }
    Verifica se con questo codice i file vengono effettivamente trasferiti o se vi sono errori/eccezioni.

    Il codice chiude la socket dopo il trasferimento di un file, ma è solo per capire se il trasferimento del singolo file funziona oppure no.


    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

  7. #7
    Per prima cosa molte GRAZIE per il tempo che mi hai dedicato, stavo cercando di trovare una soluzione e o dovuto controllare tutto il codice, mi sono accorto che il problema dovrebbe essere dovuto (per ora funziona) al fatto che scrivevo e leggevo sulla socket non in modo diciamo sincronizzato in questo modo si verificava il problema suddetto.
    Ti vorrei chedere delle cose se puoi aiutarmi, hai parlato in precedenza di un protocollo di
    comunicazione, io per sincronizzare la lettura dalla socket faccio in modo che il client e il
    server si scambiamo messaggi che sono delle stringhe del tipo "continua" e dall'altro lato controllano che la stringa ricevuta sia quella per andare avanti, è un buon modo o ne puoi suggerire un altro. Un altra cosa che vorrei chiederti e che dovrei stampare la dimensione del file in Mb, ottenuta questa facendo divisioni per 1024 come faccio a stampare solo fino alla seconda cifra decimale del tipo Mb 7.65 e non del tipo Mb 7.651201248168945.

    GRAzie

  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Quello che hai fatto, cioè "stabilire un modo per sincronizzare client e server attraverso delle stringhe" è già, di per se, un protocollo. Se con questo protocollo non hai problemi, allora significa che il protocollo è stabile e lo puoi tranquillamente usare.

    Per quanto riguarda, invece, la stampa della dimensione del file in MB senza troppi decimali, consiglio di usare un NumberFormat. Un esempio:

    codice:
    import java.text.*;
    ...
    double dimFile = ...;   // Qui ho la dimensione espressa in MB (con tutti i decimali)
    
    // Ottengo un NumberFormat
    NumberFormat nf = NumberFormat.getInstance( Locale.ITALY );
    
    // Imposto il numero massimo di decimali che voglio (es: 2)
    nf.setMaximumFractionDigits( 2 );
    
    // Imposto che voglio sempre vedere almeno 2 decimali (es: 7,3 --> 7,30; 7 --> 7,00)
    // (non è obbligatorio)
    nf.setMinimumFractionDigits( 2 );
    
    // Voglio o non voglio il puntino di raggruppamento delle migliaia?
    nf.setGroupingUsed( true );   // In questo caso ho detto di SI
    
    // Ok: ora formatto il valore e ottengo la stringa da visualizzare
    String daVisualizzare = nf.format( dimFile );
    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

  9. #9
    Ci sono due problemi:
    1) Non riesco a fargli stampare solo fino alla seconda cifra decimale ma ne mette 3.
    2) Il punto non viene messo ma c'è la virgola

    Ti posto un esempio di quello che ho fatto:

    codice:
    package number;
    import java.text.*;
    import java.util.Locale;
    
    public class Main {
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            // TODO code application logic here
             double val= 4.9832344222 ;
             NumberFormat n_f = NumberFormat.getInstance(Locale.ITALY);
             n_f.setMinimumFractionDigits(2);
             n_f.setGroupingUsed(true);
             String dimMB = n_f.format(val);
             System.out.println("Valore decimanle: "+val+" NumberFormat: " +dimMB);
        }
    
    }
    
    
    Stampa
    
    Valore decimanle: 4.9832344222 NumberFormat: 4,983
    Non mi sembra di aver fatto nessun errore ma non capisco....

  10. #10
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Originariamente inviato da fuoricorso
    Ci sono due problemi:
    1) Non riesco a fargli stampare solo fino alla seconda cifra decimale ma ne mette 3.
    2) Il punto non viene messo ma c'è la virgola

    Ti posto un esempio di quello che ho fatto:

    codice:
    package number;
    import java.text.*;
    import java.util.Locale;
    
    public class Main {
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            // TODO code application logic here
             double val= 4.9832344222 ;
             NumberFormat n_f = NumberFormat.getInstance(Locale.ITALY);
             n_f.setMinimumFractionDigits(2);
             n_f.setGroupingUsed(true);
             String dimMB = n_f.format(val);
             System.out.println("Valore decimanle: "+val+" NumberFormat: " +dimMB);
        }
    
    }
    
    
    Stampa
    
    Valore decimanle: 4.9832344222 NumberFormat: 4,983
    Non mi sembra di aver fatto nessun errore ma non capisco....
    Con la parte in grassetto stai dicendo che vuoi ALMENO 2 cifre decimali. Serve a riempire di zeri nel caso in cui non ci fossero sufficienti cifre decimali.

    Per impostare AL MASSIMO due cifre decimali devi usare setMaximumFractionDigits(), che non hai messo (vedi il mio esempio poco più su)

    2) setGroupingUsed() serve a mettere il punto di raggruppamento delle migliaia... chiaro che se hai un numero minore di 1000 (come nel tuo esempio), non vedi nessun punto... dopo la virgola non si usano i raggruppamenti.

    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

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.