Problem with file transfer via socket with java

0

I'm 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 correctly, however when I put a while so that when sending once it might give the option to send again or leave, ended up giving error in the receipt of the file. I can not solve this problem, could anyone help me? Below I am sending the complete code with the output that I put to test how much was being read from the file on the client machine and received by the server. And I do not know if it's needed, 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");


    }


}

Client exit:

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

Server output

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 did not leave the while. He did not receive the -1 he was receiving before to warn the end of the file. And so did not print on the screen that the receipt was successful.

    
asked by anonymous 31.07.2016 / 05:40

1 answer

0

I was able to reach a solution, I just changed the method of sending File and received File and before the method of sending the file I put a Thread.sleep (200). I think it might be less than 200, but I have not tested it.

The code to receive the file was 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 file upload code was 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 timing of the methods, when putting the Thread.sleep () code waiting until the functions being executed above stop for enough time for the method that gets 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 it.

    
02.08.2016 / 21:06