Boa tarde senhores, após pesquisar no google e ler algumas referências aqui do guj, pude ver que não é recomendável utilizar ObjectOutputStream em conexões via socket.
Tudo bem, implementei utilizando DataOutputStream, e aí do outro lado leio com DataInputStream. O problema é que na leitura pude ver que a sequencia por vezes e aleatoriamente chega com menos bytes do que deveria.
try{
if (Atualizador.getServidor() == null) throw new ServidorLocalException();
DataInputStream input = null;
DataOutputStream output = null;
long idServer = Atualizador.getServidor() == null || Atualizador.getServidor().getServidor() == null ? 0
: Atualizador.getServidor().getServidor().getIdConferencia();
String ip = Servidor.IP_SERVIDOR_MASTER;
while(!Thread.currentThread().isInterrupted() || encerrar){
try{
setStatus("RODANDO");
socket = new Socket(ip, getPorta());
Map<Atualizavel,List> mapaEnvio = this.getMapaEnvio(1);
byte[] dadosEnvio = Atualizador.getConversor().getBytesObjeto(mapaEnvio);
String md5Envio = Criptografa.criptografaMD5(dadosEnvio);
int tamanhoEnvio = dadosEnvio.length;
System.out.println("Servidor Secundário: Tentando conexão.. " + ip + ":" + getPorta());
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
output.writeLong(idServer);
output.writeInt(tamanhoEnvio);
output.writeUTF(md5Envio);
System.out.println("Servidor Secundário: Total enviado... " + tamanhoEnvio + " ID:" + idServer);
int idx = 0, quantEnviada = 0;
while(quantEnviada < tamanhoEnvio){
int tam = Atualizador.TAMANHO_ARRAY;
if (tamanhoEnvio - quantEnviada < Atualizador.TAMANHO_ARRAY){
tam = tamanhoEnvio - quantEnviada;
}
output.write(dadosEnvio, idx, tam);
quantEnviada += tam;
idx += tam;
}
output.flush();
System.out.println("Servidor Secundário: Mapa enviado...");
boolean envioSucesso = input.readBoolean();
int tamanhoRecebido = input.readInt();
String md5Recebida = input.readUTF();
byte[] recebidos = new byte[tamanhoRecebido];
idx = 0;
int quantRecebida = 0;
while(tamanhoRecebido > quantRecebida){
int tam = Atualizador.TAMANHO_ARRAY;
if (tamanhoRecebido - quantRecebida < Atualizador.TAMANHO_ARRAY){
tam = tamanhoRecebido - quantRecebida;
}
System.out.println("LENDO ---------->" + input.read(recebidos, idx, tam));
quantRecebida += tam;
idx += tam;
}
Map<Atualizavel,List> mapaRecebido = null;
boolean recepcaoBemSucedido = false;
//Confere a md5 enviada com a recebida, se ok carrega os dados no bd.
String md5RecebidaAConferir = Criptografa.criptografaMD5(recebidos);
System.out.println("Servidor Secundário: md5RecebidaAConferir=" + md5RecebidaAConferir
+ " md5Recebida=" + md5Recebida);
if (md5RecebidaAConferir != null && md5Recebida != null){
mapaRecebido = Atualizador.getConversor().getObjeto(recebidos);
recepcaoBemSucedido = md5RecebidaAConferir.equalsIgnoreCase(md5Recebida);
}
output.writeBoolean(recepcaoBemSucedido);
output.flush();
input.close();
output.close();
if (recepcaoBemSucedido){
super.carregarDados(mapaRecebido, 1);
System.out.println("Servidor Secundário: Dados carregados... ");
}
if (envioSucesso){
System.out.println("Servidor Secundário: Dados marcados... ");
super.marcarEnviados(mapaEnvio, 1);
}
System.out.println("\n\n");
}catch(ConnectException ce){
}catch(SocketException se){
}catch(NullPointerException npe){
}
O código do outro lado:
try{
input = new DataInputStream(getSocket().getInputStream());
output = new DataOutputStream(getSocket().getOutputStream());
//Recebe o codigo de replicacao do servidor secundário
this.setCodigoAtualizacao(input.readLong());
//Recebe o tamanho do array[] que será enviado
this.setTamanhoRecebido(input.readInt());
//Recebe para futura conferencia um md5 correspondente ao array de bytes
this.setMd5Recebida(input.readUTF());
byte[] recebidos = new byte[this.getTamanhoRecebido()];
System.out.println("Servidor Master Recebendo... id: " + this.getCodigoAtualizacao() + " Total Bytes: " + this.getTamanhoRecebido());
//recebe os pacotes do array[]
int idx = 0;
while(this.getQuantidadeRecebida() < this.getTamanhoRecebido()){
int tam = Atualizador.TAMANHO_ARRAY;
if (this.getTamanhoRecebido() - this.getQuantidadeRecebida() < Atualizador.TAMANHO_ARRAY){
tam = this.getTamanhoRecebido() - this.getQuantidadeRecebida();
}
input.read(recebidos, idx, tam);
this.adicionaQuantidadeRecebida(tam);
idx += tam;
}
System.out.println("Servidor Master Recebendo... Mapa do servidor secundário...");
//Confere a md5 enviada com a recebida, se ok carrega os dados no bd.
String md5RecebidaAConferir = Criptografa.criptografaMD5(recebidos);
if (md5RecebidaAConferir != null && this.getMd5Recebida() != null){
this.setRecepcaoBemSucedido(md5RecebidaAConferir.equalsIgnoreCase(this.getMd5Recebida()));
this.setMapaRecebido(conversor.getObjeto(recebidos));
}
System.out.println("Servidor Secundário: md5RecebidaAConferir=" + md5RecebidaAConferir
+ " md5Recebida=" + md5Recebida);
//Prepara o mapa de dados que deverão ser enviados para o servidor secundário
Map<Atualizavel,List> mapaEnvio = AtualizadorMaster.getInstance().getMapaEnvio(this.getCodigoAtualizacao());
System.out.println("Servidor Master Mapa preparado para envio ");
//Converte o mapa em array[]
byte[] dadosEnvio = conversor.getBytesObjeto(mapaEnvio);
String md5Envio = Criptografa.criptografaMD5(dadosEnvio);
int tamanho = dadosEnvio.length;
int quantEnviada = 0;
output.writeBoolean(this.isRecepcaoBemSucedido());
output.writeInt(tamanho);
output.writeUTF(md5Envio);
System.out.println("Servidor Master Total a enviar----> tamanho: " + tamanho + " MD5 Envio: " + md5Envio );
idx = 0;
while(quantEnviada < tamanho){
int tam = Atualizador.TAMANHO_ARRAY;
if (tamanho - quantEnviada < Atualizador.TAMANHO_ARRAY){
tam = tamanho - quantEnviada;
}
output.write(dadosEnvio, idx, tam);
System.out.println("Escrito --------> " + idx + " len: " + tam);
quantEnviada += tam;
idx += tam;
output.flush();
}
this.setEnvioBemSucedido(input.readBoolean());
if (this.isEnvioBemSucedido()){
AtualizadorMaster.getInstance().marcarEnviados(mapaEnvio, codigoAtualizacao);
System.out.println("Servidor Master marcando dados... ");
}
if (this.isRecepcaoBemSucedido()){
AtualizadorMaster.getInstance().carregarDados(mapaRecebido, codigoAtualizacao);
System.out.println("Servidor Master carregando dados... ");
}
System.out.println("\n\n");
}catch(Exception ex){
ex.printStackTrace();
}finally{
try{
input.close();
output.close();
socket.close();
}catch(Exception ex){}
}
}
Em seguida fiz uma leitura dos dados, e na recepção ocorre o seguinte:
Servidor Secundário: Mapa enviado…
LENDO ---------->512
LENDO ---------->512
LENDO ---------->512
LENDO ---------->512
LENDO ---------->512
LENDO ---------->321
LENDO ---------->512
LENDO ---------->94
Servidor Secundário: md5RecebidaAConferir=e37e5da97cc0e8904a72a0c50bdd723a md5Recebida=fdf9e870bd995f3126dea875272ede2c
Só para resumir, no 6º "LENDO" deveriar estar 512 (Confirmado 512 no envio) (nesse array recebido houve, acredito, ulguma perda de dados) isso ocorre de forma aleatória e ora vem 512 ora não.
Alguém saberia dizer como fazer algo mais estável ?
ps. a rede está ok cabeamento novo, ativos novos e testados com diferentes equipamentos, a culpa não é da rede.
Desde já obrigado.