Problem with file transfer via java socket

Asked

Viewed 1,081 times

0

I am trying to make a client/server program that accepts more than one client and that client sends files to the server. The transfer was working properly, however when I put a while so that when sending once it can give the option to send again or quit, ended up giving error in receiving the file. I can’t solve this problem, can someone help me? Below I am sending the complete code with the output I put to test how much was being read from the file on the client machine and received by the server. And I don’t know if it’s necessary, but the file I’m sending has 212,594 bytes and my IDE is eclipse.

Client:

public class AplicaçãoCliente {

    public static void main(String[] args) throws UnknownHostException, IOException {

        Scanner scan = new Scanner(System.in);

        System.out.println("informe ip:");

        String ip = scan.nextLine();

        System.out.println("informe porta:");

        int porta = scan.nextInt();

        Socket socket = new Socket(ip, porta);

        System.out.println("O cliente se conectou ao servidor!");

        new Cliente(socket).conectar();

        System.out.println("fim da execução");
    }
}


public class Cliente {

    private Socket cliente;
    private PrintStream saida;
    private Scanner teclado;

    public Cliente(Socket cliente) {
        this.cliente = cliente;

    }

    public void conectar() throws IOException{

        teclado = new Scanner(System.in);
        saida = new PrintStream(cliente.getOutputStream());
        String continuar = "s";

        System.out.println("------------------BEM-VINDO AO SERVIDOR------------------");
        System.out.println();

        while(continuar.equals("s")){//while adicionado que fez dar o erro

            System.out.println();
            System.out.println("Digite comando:");



            String comando = teclado.nextLine();


            saida.println(comando);

            if(comando.equals("upload")){

                enviarArquivo("/home/felipe/document.pdf");
            }else if(comando.equals("sair")){
                continuar = "n";
            }else{
                System.out.println("comando não existente");
            }
        }
        cliente.close();
    }

    private void enviarArquivo(String caminho) throws IOException{

        FileInputStream fileIn = new FileInputStream(caminho);//caminho do arquivo que sera enviado

        OutputStream out = cliente.getOutputStream();

        int tam = 4096;
        byte[] buffer = new byte[tam];
        int lidos = 0;
        int i = 0;

        lidos = fileIn.read(buffer, 0, tam);
        System.out.println(i++ + " - lidos: " + lidos);
        while (lidos > 0) {

            out.write(buffer, 0, lidos);
            lidos = fileIn.read(buffer, 0, tam);
            System.out.println(i++ + " - lidos: " + lidos);
        }

        out.flush();
        fileIn.close();

        System.out.println("enviado com sucesso");

    }
}

The Server:

public class AplicaçãoServidor {

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        // inicia o servidor
        Servidor servidor = new Servidor(12345);

        servidor.executa();

        System.out.println("fim");
    }
}

public class Servidor {

    private int porta;

    private ServerSocket servidor;

    public Servidor(int porta) {

        this.porta = porta;

    }

    public void executa() throws IOException {


        Socket cliente;
        servidor = new ServerSocket(this.porta);

        System.out.println("Porta 12345 aberta!");

        while(true){

            // aceita um cliente

            cliente = servidor.accept();

            System.out.println("Nova conexão com o cliente " +

            cliente.getInetAddress().getHostAddress());



            // cria tratador de cliente numa nova thread

            ThreadServidor thread = new ThreadServidor(cliente);

            new Thread(thread).start();



        }
    }

}

public class ThreadServidor implements Runnable {

    private Socket cliente;

    private Scanner entrada;


        public ThreadServidor(Socket cliente) {

        this.cliente = cliente;


    }

    public void run() {

        try {

            entrada = new Scanner(this.cliente.getInputStream());
            String continuar = "s";

            while(continuar.equals("s")){// while adicionado que originou o erro

                String resposta = entrada.nextLine();

                if(resposta.equals("upload")){
                    receberArquivo("/home/felipe/Downloads/documento.pdf");
                }else if(resposta.equals("sair")){
                    continuar = "n";
                }else{
                    System.out.println("comando não existente");
                }
            }
            cliente.close();
        } catch (IOException e) {

            e.printStackTrace();
        }

    }

    public void receberArquivo(String caminho) throws IOException {

        FileOutputStream fos = new FileOutputStream(caminho);// o caminho onde o arquivo sera escrito

        int tam = 4096;
        byte[] buffer = new byte[tam];
        int lidos = 0;

        InputStream in = cliente.getInputStream();

        int i = 0;


        lidos = in.read(buffer, 0, tam);
        System.out.println(i++ + " - lidos: " + lidos);

        while (lidos > 0) {

            fos.write(buffer, 0, lidos);
            lidos = in.read(buffer, 0, tam);
            System.out.println(i++ + " - lidos: " + lidos);
        }

        fos.flush();
        fos.close();

        System.out.println("arquivo recebido");


    }


}

The Departure of the Customer:

0 - lidos: 4096
1 - lidos: 4096
2 - lidos: 4096
3 - lidos: 4096
4 - lidos: 4096
5 - lidos: 4096
6 - lidos: 4096
7 - lidos: 4096
8 - lidos: 4096
9 - lidos: 4096
10 - lidos: 4096
11 - lidos: 4096
12 - lidos: 4096
13 - lidos: 4096
14 - lidos: 4096
15 - lidos: 4096
16 - lidos: 4096
17 - lidos: 4096
18 - lidos: 4096
19 - lidos: 4096
20 - lidos: 4096
21 - lidos: 4096
22 - lidos: 4096
23 - lidos: 4096
24 - lidos: 4096
25 - lidos: 4096
26 - lidos: 4096
27 - lidos: 4096
28 - lidos: 4096
29 - lidos: 4096
30 - lidos: 4096
31 - lidos: 4096
32 - lidos: 4096
33 - lidos: 4096
34 - lidos: 4096
35 - lidos: 4096
36 - lidos: 4096
37 - lidos: 4096
38 - lidos: 4096
39 - lidos: 4096
40 - lidos: 4096
41 - lidos: 4096
42 - lidos: 4096
43 - lidos: 4096
44 - lidos: 4096
45 - lidos: 4096
46 - lidos: 4096
47 - lidos: 4096
48 - lidos: 4096
49 - lidos: 4096
50 - lidos: 4096
51 - lidos: 3698
52 - lidos: -1
enviado com sucesso

The output from the Server

0 - lidos: 4096
1 - lidos: 4096
2 - lidos: 4096
3 - lidos: 4096
4 - lidos: 4096
5 - lidos: 4096
6 - lidos: 4096
7 - lidos: 4096
8 - lidos: 4096
9 - lidos: 4096
10 - lidos: 4096
11 - lidos: 4096
12 - lidos: 4096
13 - lidos: 4096
14 - lidos: 4096
15 - lidos: 4096
16 - lidos: 4096
17 - lidos: 4096
18 - lidos: 4096
19 - lidos: 4096
20 - lidos: 4096
21 - lidos: 4096
22 - lidos: 4096
23 - lidos: 4096
24 - lidos: 4096
25 - lidos: 4096
26 - lidos: 4096
27 - lidos: 4096
28 - lidos: 4096
29 - lidos: 4096
30 - lidos: 4096
31 - lidos: 4096
32 - lidos: 4096
33 - lidos: 4096
34 - lidos: 4096
35 - lidos: 4096
36 - lidos: 4096
37 - lidos: 4096
38 - lidos: 4096
39 - lidos: 4096
40 - lidos: 4096
41 - lidos: 4096
42 - lidos: 4096
43 - lidos: 4096
44 - lidos: 4096
45 - lidos: 4096
46 - lidos: 4096
47 - lidos: 4096
48 - lidos: 4096
49 - lidos: 4096
50 - lidos: 4096
51 - lidos: 3698

He didn’t quit while. He didn’t get the -1 he was getting before to warn end of file. And so did not print on the screen that the receipt was successful.

1 answer

0


I managed to reach a solution, I only changed the method of sending File and receiving File and before the method of sending the file I put a Thread.Sleep(200). I believe it may be less than 200, but I haven’t tested.

The code to receive File has been changed to look like this:

public void receiveFile(String path) throws Ioexception {

        try {

        int bytesRead;
        DataInputStream clientData = new DataInputStream(
                cliente.getInputStream());

        String fileName = clientData.readUTF();
        String caminhoCompleto = caminho + "/" + fileName;

        OutputStream output = new FileOutputStream((caminhoCompleto));
        long size = clientData.readLong();
        byte[] buffer = new byte[1024];

        while (size > 0
                && (bytesRead = clientData.read(buffer, 0,
                        (int) Math.min(buffer.length, size))) != -1) {
            output.write(buffer, 0, bytesRead);
            size -= bytesRead;
        }

        output.close();

        System.out.println("Arquivo " + fileName
                + " recebido pelo cliente.");

    } catch (FileNotFoundException e) {
        e.printStackTrace();
        System.out.println("Arquivo não encontrado");
    }

}

The send code has been changed to

public void sendFile(String filename) throws Ioexception {

        try {

        File myFile = new File(fileName);
        byte[] mybytearray = new byte[(int) myFile.length()];

        FileInputStream fis = new FileInputStream(myFile);
        BufferedInputStream bis = new BufferedInputStream(fis);


        DataInputStream dis = new DataInputStream(bis);
        dis.readFully(mybytearray, 0, mybytearray.length);


        OutputStream os = cliente.getOutputStream();


        DataOutputStream dos = new DataOutputStream(os);
        dos.writeUTF(myFile.getName());
        dos.writeLong(mybytearray.length);
        dos.write(mybytearray, 0, mybytearray.length);
        dos.flush();

        System.out.println("Arquivo "+fileName+" enviado para cliente.");

    } catch (FileNotFoundException e) {
        System.err.println("Arquivo não existe!");
    } 
}

With this my conclusion was that the error was in the synchronization of the methods,when placing the Thread.Sleep() the code waits until the functions being executed above stops long enough for the method that receives the file to be locked in the method of reading the bytes, so I will not send the file until the method that receives it is ready for such.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.