Problema com transferencia de arquivo com socket

3 respostas
Bocchi

Bom preciso implementar uma aplicação cliente/servidor, onde o cliente se conecta ao servidor e os dois trocam mensagens até ai nenhum problema, o problema é quando o cliente quer mandar um arquivo para o servidor, primeiro o cliente manda uma mensagem dizendo que vai enviar um arquivo, entao o servidor responde se é possivel enviar e qual porta utilizar (utilizo uma porta para cada transmissao), só que meu cliente implementa a interface runnable, e no metodo run possui um while que recebe as respostas do servidor, e quando o servidor responde as respostas sao recebidas pela escuta do metodo run e nao pela escuta do metodo enviar arquivo, entao gostaria se possivel de algumas sugestoes.

3 Respostas

Sombriks

Olá, você pode ler um arquivo como uma stream também, tão igual às streams do socket.

http://www.java2s.com/Code/JavaAPI/javax.net/Socket.htm

se houver dúvidas de como ler um arquivo na forma de uma stream,

http://www.java2s.com/Code/Java/File-Input-Output/CatalogFile-Input-Output.htm

teste com calma e combine os dois.

por fim um funnable põe uma referência fora a nível de classe ou não implemente inline, de forma anônima, e assim você poderá passar parâmetros de construtor, ou o que preferir.

tente usar pontuação correta, formatar bem o texo, pois isso ajuda a entendermos a pergunta. E se puder, mostrar o que você já fez também ajuda.

Bocchi

Desculpe pelos erros de português, definitivamente não é o meu forte. Porém você não entendeu minha duvida, não tenho dificuldades para ler ou enviar o arquivo, eu preciso na realidade uma solução para que eu possa ter um while com espera ocupada escutando as respostas do servidor, ao mesmo tempo que meu método enviar arquivo receba a porta que o servidor enviou para a transferência do arquivo, ou ainda uma solução mais elegante para o meu problema.
Atenciosamente Paulo Ricardo Bocchi.

Bocchi

Bom para islustrar melhor meu problema segue um trexo do meu código.

Arqui a classe servidor responsável por aguardar conexões dos clientes.

public class Servidor implements Runnable {

    private int porta;
    private ServerSocket servidor;

    public Servidor(int porta) {
        this.porta = porta;
    }

    public void run() {
        try {
            this.servidor = new ServerSocket(porta);
            while(true) {
                Socket cliente = this.servidor.accept();
                new Thread(new TrataCliente(cliente, this)).start();
            }
        } catch (IOException ex) {
            Logger.getLogger(ServidorTCP.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

Aqui a classe responsavel pelo tratamento dos clientes.

public class TrataCliente implements Runnable {

    private Socket cliente;
    private ServidorTCP servidor;

    private DataInputStream in;
    private DataOutputStream out;
    
    private static int BUFFER_SIZE = 8192;
    private Transferencia transferencia;
    private byte[] buffer;
    private int nBytesLidos;

    private UsuarioDAO dao;

    public TrataCliente(Socket cliente, UsuarioDAO dao, ServidorTCP servidor) {
        this.cliente = cliente;
        this.servidor = servidor;
        this.dao = dao;
        this.buffer = BUFFER_SIZE;
    }

    public void processaMensagem(Mensagem msg) throws IOException {
        if (msg.getTipo()==Mensagem.ENVIAR_ARQUIVO) {
            new Thread(new TrataRecebimento(in, msg));
            return;
        }
        if (msg.getTipo()==Mensagem.DESCONECTAR) {
            desconecta(msg);
            return;
        }
    }

    private void desconecta(Mensagem msg) throws IOException {
        msg.setTipo(Mensagem.DESCONECTAR);
        out.writeInt(msg.toString().getBytes().length);
        out.write(msg.toString().getBytes());
        out.flush();
    }

    public void run() {
        Mensagem msg = null;
        try {
            in = new DataInputStream(cliente.getInputStream());
            out = new DataOutputStream(cliente.getOutputStream());
            nBytesLidos = in.read(buffer);

            msg = new Mensagem(new String(buffer,0,nBytesLidos));
            if (msg.getTipo()==Mensagem.CONECTAR) {
                Usuario usuario = new Usuario();
                usuario.setLogin(msg.getLogin());
                usuario.setSenha(msg.getSenha());
                if (dao.carrega(usuario)!=null) {
                    msg.setTipo(Mensagem.CONEXAO_ACEITA);
                    out.write(msg.toString().getBytes());
                    out.flush();
                    while(true) {
                        int nBytes = in.readInt();
                        nBytesLidos = in.read(buffer,0,nBytes);
                        msg = new Mensagem(new String(buffer, 0, nBytesLidos));
                        System.out.println(msg);
                        processaMensagem(msg);
                    }
                }
                else {
                    msg.setTipo(Mensagem.ERRO);
                    msg.setCodErro(Mensagem.USUARIO_SENHA_INVALIDO);
                    out.write(msg.toString().getBytes());
                    out.flush();
                }
            }
        } catch (EOFException ex) {
            System.out.println("cliente desconectou!");
        } catch (FormatoException ex) {
            Logger.getLogger(TrataCliente.class.getName()).log(Level.SEVERE, null, ex);
            msg = new Mensagem();
            msg.setTipo(Mensagem.ERRO);
            msg.setCodErro(Mensagem.MENSAGEM_INVALIDA);
        } catch (IOException ex) {
            Logger.getLogger(TrataCliente.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if (in!=null) { try { in.close(); } catch (IOException ex) {} }
            if (out!=null) { try { out.close(); } catch (IOException ex) {} }
            if (cliente!=null) { try { cliente.close(); } catch (IOException ex) {} }
        }
    }

}

Aqui a classe cliente.

public class Cliente implements Runnable {
    private Socket socket;
    private int porta;
    private String host;
    private String login;
    private String senha;

    private DataOutputStream out;
    private DataInputStream in;

    private Transferencia transferencia;
    private static int BUFFER_SIZE = 8192;
    private int nBytesLidos;
    private byte buffer[];


    public Cliente(String login, String senha, String host, int porta) {
        this.login = login;
        this.senha = senha;
        this.host = host;
        this.porta = porta;
        this.buffer = new byte[BUFFER_SIZE];
        this.transferencia = new Transferencia();
    }

    public void conectar() throws IOException {
        try {
            this.socket = new Socket(host, porta);
            out = new DataOutputStream(socket.getOutputStream());
            in = new DataInputStream(socket.getInputStream());

            Mensagem msg = new Mensagem(login,senha);
            out.write(msg.toString().getBytes());
            out.flush();

            nBytesLidos = in.read(buffer);
            msg.setMensagem(new String(buffer, 0, nBytesLidos));
            if (msg.getTipo()==Mensagem.CONEXAO_ACEITA) {
                System.out.println("conexao aceita!");
            }
            else {
                System.err.println("Erro "+msg.getCodErro());
            }
        } catch (FormatoException ex) {
            Logger.getLogger(ClienteTCP.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnknownHostException ex) {
            Logger.getLogger(ClienteTCP.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void enviaMensagem(Mensagem msg) throws IOException {
            if (msg.getTipo()==Mensagem.ENVIAR_ARQUIVO) {
                 msg.setNomeDoArquivo(arquivo.getName());
                 msg.setTamanhoArquivo(arquivo.length());
            }
            out.writeInt(msg.toString().getBytes().length);
            out.write(msg.toString().getBytes());
            out.flush();
    }

    public void enviaArquivo(File arquivo) throws IOException, InterruptedException {

        Mensagem msg = new Mensagem();
        msg.setTipo(Mensagem.ENVIAR_ARQUIVO);
        msg.setNomeDoArquivo(arquivo.getName());
        msg.setTamanhoArquivo(arquivo.length());
        out.writeInt(msg.toString().getBytes().length);
        out.write(msg.toString().getBytes());
        out.flush();
 
        nBytes = in.readInt();                                      //aqui é o problema, o método nao recebe a resposta do servidor, por que o método run recebe.
        nBytesLidos = in.read(buffer,0,nBytes);
        msg.set(new String(buffer,0,nBytesLidos));
        if (msg.getTipo == Mensagem.ENVIAR_ARQUIVO_OK) {
            new Thread(TrataEnvio(new FileInputStream(arquivo), msg.getPorta);
        }

    }

    public void run() {
        while (true) {
            try {
                int nBytes = in.readInt();                                                                         //quando eu envio o arquivo a resposta é recebida aqui.
                nBytesLidos = in.read(buffer, 0, nBytes);
                Mensagem msg = new Mensagem(new String(buffer,0,nBytesLidos));
                if (msg.getTipo()==Mensagem.DESCONECTAR) {
                    break;
                }

            } catch (IOException ex) {
                Logger.getLogger(ClienteTCP2.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    in.close();
                } catch (IOException ex) {
                    Logger.getLogger(ClienteTCP2.class.getName()).log(Level.SEVERE, null, ex);
                }
                try {
                    out.close();
                } catch (IOException ex) {
                    Logger.getLogger(ClienteTCP2.class.getName()).log(Level.SEVERE, null, ex);
                }
                try {
                    socket.close();
                } catch (IOException ex) {
                    Logger.getLogger(ClienteTCP2.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
}
Criado 17 de setembro de 2010
Ultima resposta 18 de set. de 2010
Respostas 3
Participantes 2