Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    Client Server invio file.... help me

    Mi scuso ci sono varie discussioni in proposito ma c'è un po' di confusione mi date una mano per favore
    Devo inviare un file dal server al client e non ho ben capito il tipo di stream da utilizzare alcuni usano solo FileInputStream e FileOutputStream altri invece una combinazione di questi con ObjectInputStream e ObectOutputStream

    Nel Server

    codice:
    ............................
    
    OutputStream os = socket.getOutputStream();
    
    FileInputStream fis = new FileInputStream("C:\\file.mp3");
    byte[] buffer = new byte[1024];
    int pos=0;
    try{
       while((pos=fis.read(buffer))!=-1)
               os.write(buffer, 0, pos);
       }
    catch(IOException e){e.printStackTrace();}
    
    ..............................
    Nel Client

    codice:
    .......................
    
    
    File salva = new File (nome);
    FileOutputStream  fos = new FileOutputStream(salva);
    InputStream is = socket.getInputStream();
    byte[] buf = new byte[1024];
    int p = 0;
    while((p=is.read(buf))!=-1) {
         fos.write(buf, 0, p);
        }
    ...........................................
    Questa è una soluzione o funziona solo perchè il client e server sono sulla stessa macchina.Oppure devo mettere i dati in un paccheto di byte e spedirli con ObjectOutputStream (writeObject) e leggerli con ObjectInputStream (readObject)...
    Un'altra domanda se il file e di grandi dimensioni come fare a inviare una quantita maggiore di dati contemporaneamete invece di leggere ed scrivere solo 1024 byte

  2. #2
    ho trovato questa soluzione sembra che funzioni, mi permette di inviare più dati contemporaneamente senza leggere ed inviare un array di byte[1024] di piccole dimensioni.Perchè ho il problema che il file può essere di grandi dimensioni.

    LATO SERVER
    codice:
    ...............................
    
    File invia = new File("C:\\audio.mp3");
    ObjectOutputStream o = new ObjectOutputStream(sock_client.getOutputStream()); 
    FileInputStream is = new FileInputStream(invia);
    
    //in questo modo dovrei sapere la dimensione del file da spedire e creare un
    //array di byte di tale dimensione, leggo i dati e li scrivo nella socket
    
    byte[] dati = new byte[is.available()];
    is.read(dati);
    o.writeObject(dati);
    ..............
    LATO CLIENT

    codice:
    ..........................................
    
    File salva = new File("C:\\traccia.mp3");
    ObjectInputStream i = ObjectInputStream(s.getInputStream());
    FileOutputStream os = new FileOutputStream(salva)
    
    //leggo i dati inviati dal server e li scrivo nel file
    byte[] buf = (byte[])i.readObject();
    fos.write(buf);
    ...........
    E' una soluzione valida? funziona nel caso che il client e server sono su macchine separate, potete aiutarmi sul metodo:
    public native int available() throws IOException;
    di FileInputSteam può causarmi dei problemi?

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Originariamente inviato da fuoricorso
    E' una soluzione valida?
    No, non sempre.

    funziona nel caso che il client e server sono su macchine separate, potete aiutarmi sul metodo:
    public native int available() throws IOException;
    di FileInputSteam può causarmi dei problemi?
    Il problema non è il metodo available(). Il problema vero è che se il file è di grosse dimensioni puoi incorrere nei seguenti problemi:

    1) La memoria a disposizione della JVM potrebbe non essere sufficiente ad allocare un array di dimensione pari al file.

    2) Se anche la memoria fosse sufficiente, avresti dei rallentamenti con i file di grosse dimensioni.

    3) Quasi certamente rischi di creare dei grossi problemi all'infrastruttura di rete.

    Il mio consiglio è quello di leggere il file a blocchi e di spedire ciascun blocco separatamente: non sei obbligato a costruire blocchi di 1 KB (nessuno costruisce più blocchi così piccoli), puoi tranquillamente costruire blocchi grandi qualche decina di KB (anche qualche centinaia, volendo), ma non inoltrare pacchetti grandi esattamente quanto tutto il file perchè, appunto, la memoria potrebbe non essere sufficiente all'allocazione.

    Piuttosto mi concrentrerei di più sul protocollo: per quanto quello sia più che sufficiente, è sempre bene arricchirlo con qualche informazione.

    Ad esempio: è sempre buona norma inviare al client la dimensione totale del file. Questo permette anche al client di sapere se tutto è andato liscio, oltra a permettergli di sapere quando fermarsi con le letture dalla socket.


    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

  4. #4
    GRAZIE GRAZIE GRAZIE per la risposta.
    I problemi da te elencati dovrei averli anche nel caso il mio server, dovrebbe risiedere su una macchina molto "potente" il cui compito è proprio quello di inviare file a ipotetici client?

    Mi puoi toglire il dubbio che il mio codice vada bene anche su host diversi, visto che io lavoro solo sul mio PC dove c'è sia il cliente che il sever.

  5. #5
    Originariamente inviato da fuoricorso
    GRAZIE GRAZIE GRAZIE per la risposta.
    I problemi da te elencati dovrei averli anche nel caso il mio server, dovrebbe risiedere su una macchina molto "potente" il cui compito è proprio quello di inviare file a ipotetici client?

    Mi puoi toglire il dubbio che il mio codice vada bene anche su host diversi, visto che io lavoro solo sul mio PC dove c'è sia il cliente che il sever.
    P.S Se si devono usare blocchi di dimensioni maggiori ad esempio 10 kb, la dimensione del blocco inviato di volta in volta deve essere a conoscenza sia del client che del server, cioè quando il client legge deve usare una array di byte uguale a quello inviato, se l'ultimo frammento inviato è inferiore alla dimensione dell'array di byte usato ci possono essere dei problemi.

    se il file è di 175kb e l'array di 10kb quando viene inviato l'ultimo blocco che dovrebbe essere di 5kb si possono verificare dei problemi?

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Originariamente inviato da fuoricorso
    GRAZIE GRAZIE GRAZIE per la risposta.
    I problemi da te elencati dovrei averli anche nel caso il mio server, dovrebbe risiedere su una macchina molto "potente" il cui compito è proprio quello di inviare file a ipotetici client?
    In quel caso non dovresti avere problemi, ma il problema lo ritrovi nel client: se il client non ha sufficiente memoria per poter allocare un array di grandi dimensioni l'applicazione termina con un OutOfMemoryError.
    In ogni caso, devi tenere presente che potresti non ottenere alcun beneficio se il client non ha una linea internet in grado di ricevere tutti quei dati in poco tempo e vi sarebbero rallentamenti.

    Mi puoi toglire il dubbio che il mio codice vada bene anche su host diversi, visto che io lavoro solo sul mio PC dove c'è sia il cliente che il sever.
    Sì: la comunicazione tramite socket funziona sia in locale che su Intranet/Internet.

    P.S Se si devono usare blocchi di dimensioni maggiori ad esempio 10 kb, la dimensione del blocco inviato di volta in volta deve essere a conoscenza sia del client che del server, cioè quando il client legge deve usare una array di byte uguale a quello inviato, se l'ultimo frammento inviato è inferiore alla dimensione dell'array di byte usato ci possono essere dei problemi.
    Il client può usare un array di dimensioni a piacere:
    codice:
    byte[] buffer = new byte[5 * 1024];   // buffer da 5 KB
    int byteLetti = is.read( buffer );
    Con questa istruzione verranno letti al massimo 5 KB di dati. Il numero effettivo di byte letti viene ritornato dalla read() nella variabile "byteLetti". Tale variabile potrà avere valori da -1 (errore in lettura, socket chiusa, fine dei dati) fino a 5120 (la dimensione massima dell'array).
    Quindi, non c'è proprio alcun problema. Ed è importante sempre usare la variabile "byteLetti" per sapere quanti sono esattamente i valori "validi" dell'array. Se vengono letti 20 byte, i primi 20 byte saranno byte di dati validi, i rimanenti non vanno presi in considerazione.

    se il file è di 175kb e l'array di 10kb quando viene inviato l'ultimo blocco che dovrebbe essere di 5kb si possono verificare dei problemi?
    Come detto sopra, no, perchè vanno considerati solo i primi N byte e questi N è il valore della variabile "byteLetti".

    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
    GRAZIE

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.