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.
Problema com transferencia de arquivo com socket
3 Respostas
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.
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.
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);
}
}
}
}
}