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

    Trasferimento file via socket (andata e ritorno)

    Ciao a tutti, è il mio primo post di richiesta d'aiuto su questo forum...ho la necessità di creare un server che riceve un file da client, lo elabora, e rimanda indietro il risultato. Ora, omettendo la parte dell'elaborazione, ho dei problemi a far viaggiare i file in entrambe le direzioni. Il problema suppongo sia dal lato server, che mi da errore di lettura dal socket.

    In pratica il percorso Client->server funziona, il file viene trasferito e salvato correttamente. Al momento di far viaggiare un qualunque file "al contrario" cioè Server->Client mi da errore il Server.

    Vi allego il codice del Server e del Client

    Server:
    codice:
    import java.util.*;
    import java.net.*;
    import java.io.*;
    
    public class Server {
        private static final int SERVER_PORT = 9977;
        private static final String SEND_DIR = "C:/k10.doc";
        private static final String SAVE_DIR = "C:/HelloWorld.class";
        private Socket socket;
            
        
        public static void main (String[] args) throws IOException{
            File file=null;
            Socket s =null;
            
            ServerSocket ss = new ServerSocket(SERVER_PORT);
            System.out.println("Sono sulla " + ss);
    
            s = ss.accept();
            System.out.println("Conessione da " + s);
    
            System.out.println("presa in carico nuova connessione da " + s);
            
            File inFile = null;
            try{
                ObjectInputStream oin = new ObjectInputStream(s.getInputStream());
                inFile = (File) oin.readObject();
                File saveFile = new File(SAVE_DIR);           
                save(inFile, saveFile);
            }
            catch (IOException e){
                e.printStackTrace();
            }
            catch (ClassNotFoundException e){
                e.printStackTrace();
            }
            
            System.out.println("File Ricevuto da Server");
            
            File file2=new File(SEND_DIR);
            ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
            oos.reset();
            oos.writeObject(file2);
            oos.flush();
            oos.close();
            
            System.out.println("File inviato da Server - Chiusura Socket");
            
            try {
                s.close();
            } 
            catch (IOException e) { 
                e.printStackTrace();
            }
        }
        
        public static void save(File in, File out) throws IOException {
            System.out.println(" --ricezione file " + in.getName());
            System.out.println(" --dimensione file " + in.length());
             FileInputStream fis  = new FileInputStream(in);
            FileOutputStream fos = new FileOutputStream(out);
     
            byte[] buf = new byte[1024];
            int i = 0;
            while((i=fis.read(buf))!=-1) {
                  fos.write(buf, 0, i);
              }
              fis.close();
              fos.close();
     
              System.out.println(" --ricezione completata");
      }
    }
    e questo è il codice del Client.

    codice:
    import java.io.*;
    import java.net.*;
    import java.util.*;
    
    
    public class Client {
        private static final String SERVER_HOST = "127.0.0.1";
        private static final int SERVER_PORT = 9977;
        private static final String SAVE_DIR = "C:/Result";
        private static final String SEND_DIR = "F:/HelloWorld.class"; 
        
        public static void main (String[] args){
            Socket socket = null;
            try {
                socket = new Socket(SERVER_HOST, SERVER_PORT);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            System.out.println("Client Connesso" + socket);
            
            File file2=new File(SEND_DIR);
            try{
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.reset();
            oos.writeObject(file2);
            oos.flush();
            oos.close();
            }
            catch (IOException e){
                e.printStackTrace();
            }
            
            System.out.println("File Spedito da Client");
            
            File inFile = null;
            try{
                ObjectInputStream oin = new ObjectInputStream(socket.getInputStream());
                inFile = (File) oin.readObject();
                File saveFile = new File(SAVE_DIR + "/" + inFile.getName());           
                save(inFile, saveFile);
    
            }
            catch (IOException e){
                e.printStackTrace();
            }
            catch (ClassNotFoundException e){
                e.printStackTrace();
            }
            
            System.out.println("File Ricevuto da Client - Chiusura Socket");
            
            try {
                socket.close();
            } 
            catch (IOException e) { 
                e.printStackTrace();
            }
        }
        
        public static void save(File in, File out) throws IOException {
            System.out.println(" --ricezione file " + in.getName());
            System.out.println(" --dimensione file " + in.length());
            FileInputStream fis  = new FileInputStream(in);
            FileOutputStream fos = new FileOutputStream(out);
     
            byte[] buf = new byte[1024];
            int i = 0;
            while((i=fis.read(buf))!=-1) {
                  fos.write(buf, 0, i);
              }
              fis.close();
              fos.close();
     
              System.out.println(" --ricezione completata");
      }
    }
    alla riga in neretto netbeans mi segnala l'errore sul server (che quindi è avvenuto nella riga precedente) Software caused connection abort: socket write error
    mentre il server poi trova l'errore di socket chiuso

    Dove commetto l'errore?

    Grazie a tutti per l'aiuto

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    No no ... alt! Stai facendo un po' di confusione, il concetto non è affatto corretto anzi è proprio sbagliato di brutto!
    Stai usando la "serializzazione" per trasferire tra client e server solamente degli oggetti di tipo File. Un oggetto java.io.File è solamente una "astrazione" di un pathname nel file system locale ma non ha nulla a che fare direttamente con il contenuto del file. Inviare/ricevere oggetti File non vuol dire che stai fisicamente trasferendo il contenuto dei file. Anzi, un pathname ha senso solo nel contesto di un certo host. Il tuo programma funzionerebbe solo e ripeto solo se client/server sono sulla stessa macchina.

    Per inviare un file devi proprio aprirlo, leggere a blocchi di N byte ed inviare questi blocchi di byte sul socket. Quindi a) la serializzazione non ti serve, b) Devi modificare tutto quanto.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    ok, almeno è un punto di partenza. Ho provato una soluzione del genere: l'errore però è sempre lo stesso, cioè s.getOutputStream

    Server
    codice:
    import java.util.*;
    import java.net.*;
    import java.io.*;
    
    public class Server {
        private static final int SERVER_PORT = 9977;
        private static final String SEND_DIR = "C:/mamma.class";
        private static final String SAVE_DIR = "C:/HelloWorld.class";
        private Socket socket;
            
        
        public static void main (String[] args) throws Exception{
            File file=null;
            Socket s =null;
            
            ServerSocket ss = new ServerSocket(SERVER_PORT);
            System.out.println("Sono sulla " + ss);
    
            s = ss.accept();
            System.out.println("Conessione da " + s);
    
            System.out.println("presa in carico nuova connessione da " + s);
            
            System.out.println("Server accepts");
    
            BufferedInputStream inn = new BufferedInputStream(s.getInputStream());
            BufferedOutputStream ut = new BufferedOutputStream(new FileOutputStream(new File(SEND_DIR)));
    
            byte[] buff = new byte[1024];
            int readMe;
    
            while( (readMe = inn.read(buff)) >= 0) {
                ut.write(buff, 0, readMe);
            }
            
            inn.close();
            ut.flush();
            ut.close();
            
            System.out.println("Server ha ricevuto il file");
            
            
            BufferedInputStream fileIn = null;
            BufferedOutputStream out = null;
            
            file=new File(SEND_DIR);
            fileIn = new BufferedInputStream(new FileInputStream(file));
            out = new BufferedOutputStream(s.getOutputStream());
            byte[] buffer = new byte[1024];
    
            int numRead;
    
            while( (numRead = fileIn.read(buffer)) >= 0) {
               out.write(buffer, 0, numRead);
            }
            
            out.flush();
            out.close();
            fileIn.close();
            
            System.out.println("Server ha inviato il file");
            
            s.close();
            
        }
    }


    Client
    codice:
    public class Client {
        private static final String SERVER_HOST = "127.0.0.1";
        private static final int SERVER_PORT = 9977;
        private static final String SAVE_DIR = "C:/Result/mamma.class";
        private static final String SEND_DIR = "F:/HelloWorld.class"; 
        
        
        
        
        public static void main (String[] args) throws Exception{
            Socket socket = null;
            File file=null;
            try {
                socket = new Socket(SERVER_HOST, SERVER_PORT);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            System.out.println("Client Connesso" + socket);
            
            BufferedInputStream fileIn = null;
            BufferedOutputStream out = null;
            
            file=new File(SEND_DIR);
            fileIn = new BufferedInputStream(new FileInputStream(file));
            out = new BufferedOutputStream(socket.getOutputStream());
            byte[] buffer = new byte[1024];
    
            int numRead;
    
            while( (numRead = fileIn.read(buffer)) >= 0) {
               out.write(buffer, 0, numRead);
            }
            
            out.flush();
            out.close();
            fileIn.close();
            
            System.out.println("Client ha inviato il file");
            
            BufferedInputStream inn = new BufferedInputStream(socket.getInputStream());
            BufferedOutputStream ut = new BufferedOutputStream(new FileOutputStream(new File(SAVE_DIR)));
    
            byte[] buff = new byte[1024];
            int readMe;
    
            while( (readMe = inn.read(buff)) >= 0) {
                ut.write(buff, 0, readMe);
            }
            
            inn.close();
            ut.flush();
            ut.close();
            
            System.out.println("Client ha ricevuto il file");
            
            socket.close();
    
        }
    }
    a quanto pare nel momento in cui eseguo inn.close() sul server è come se si chiudesse il socket. Se "commento" quella riga infatti mi si creano entrembe i file ma ovviamente non mi si chiudono...come risolvo?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Beh, innanzitutto ci sono altre questioni da vedere. È chiaro che se sai che devi ricevere, fare qualcosa e poi inviare, non puoi chiudere il socket. Ma c'è un'altra questione anche importante: chi riceve come fa a "sapere" quanti byte deve leggere?? Appunto non lo sa. Deve essere il mittente a indicarlo al destinatario in qualche modo. Questo presuppone la realizzazione di un piccolo "protocollo" di comunicazione, anche minimale.

    In genere la cosa più semplice è quella di inviare 4 byte (il valore di un int) che indicano la lunghezza del file e poi subito dopo lo stream di dati con il contenuto del file. Il destinatario leggerà prima di tutto questo 'int' e saprà quanti byte leggere dopo.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    quindi dici che l'errore è nel fatto che non ho stabilito un protocollo e che quindi il ricevente non sa quanti byte leggere?

    Il socket io non lo vorrei chiudere, infatti il comando di chiusura del socket è lasciato per ultimo.

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Luca Petralia
    quindi dici che l'errore è nel fatto che non ho stabilito un protocollo e che quindi il ricevente non sa quanti byte leggere?
    Appunto .. non hai stabilito delle regole tali per cui chi riceve possa sapere cosa "aspettarsi" dallo stream.

    Originariamente inviato da Luca Petralia
    Il socket io non lo vorrei chiudere, infatti il comando di chiusura del socket è lasciato per ultimo.
    Ma in mezzo al client ad un certo punto fai una out.close(). Stai chiudendo l'OutputStream ma la documentazione di Socket dice:

    Closing the returned OutputStream will close the associated socket.

    Quindi chiudi pure il socket!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    ok, grazie mille. Vedrò di fare le modifiche adatte...non avevo controllato la documentazione del close dell'outputstream, e davo per scontato che il socket non lo chiudesse

  8. #8
    Scusa la domanda stupida, ma come faccio a leggere a byte dal socket? Le mie conoscenze di java, come è palese, sono piuttosto scarse e non riesco a trovare un metodo per dire al Buffered Reader "leggi tot byte". Con i File l'ho fatto, ma negli input stream non c'è un metodo che accetta byte[] come parametro.

    Grazie ancora

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Luca Petralia
    Scusa la domanda stupida, ma come faccio a leggere a byte dal socket? Le mie conoscenze di java, come è palese, sono piuttosto scarse e non riesco a trovare un metodo per dire al Buffered Reader "leggi tot byte". Con i File l'ho fatto, ma negli input stream non c'è un metodo che accetta byte[] come parametro.
    Se usi un BufferedInputStream ci sono i metodi:

    int read(byte[] b)
    int read(byte[] b, int off, int len)

    Chiaramente l'array di byte lo devi creare tu di una dimensione fissa/accettabile.

    Inoltre se leggi/scrivi direttamente a byte, il valore 'int' che ti avevo suggerito di usare per indicare la lunghezza lo devi trasformare tu da/a 4 byte.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  10. #10
    nel caso dell'invio della dimensione di un file posso preimpostarlo a 4 byte (mi pare sia questa la dimensione del long che mi permette di leggere la dimensione del file). Quindi l'idea sarebbe , dato che non mi serve una struttura molto flessibile, leggere dapprima il long, poi impostare il buffer di byte in base alla dimensione ricevuta, e ricevere con questo buffer l'intero file. Stesso discorso per il cammino inverso. L'impostazione la ritieni corretta oppure è migliorabile?

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.