Ler array de bytes de um socket servidor

14 respostas
P

Olá galera estou com um problema fiz um socket para se conectar com uma leitora de acesso fisico , a comunicaçõ entre leitora (servidor) e cliente é feita através de array de bytes,
o socket q eu utilizo é por meio do protocolo tcp/ip, o problema é q nem sempre vou saber o tamanho do array de bytes de resposta, e encontro problemas de estouro de array, há alguma maneira de eu saber previamente o tamanho da resposta para não ficar estanciando toda hora o array??
gratoo…

14 Respostas

K

Você pode optar em criar vários pacotes de tamanhos fixos para enviar toda a mensagem, ou até mesmo, antes de enviar a informação desejada, envia primeiro um valor inteiro que corresponde ao tamanho total da sua mensagem. Daí você instancia o array por completo e depois é só armazenar.

[]'s.

V

Como é o protocolo dessa leitora? Tipicamente, protocolos binários enviam algum tipo de cabeçalho de tamanho fixo, indicando o tamanho do array de bytes.

P

A leitora trabalha com protocolos tcp/ip , udp, rs422, mas estou utilizando o protocolo tcp/ip , e a respeito do cabeçalho não envia nada
olha o codigo que estou utilizando.

package socketpronto;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 *
 * @author Pedro Benavalli
 */
public class Cliente extends JFrame{
    
    private JTextField enter;
    private JTextArea display;
    DataOutputStream output;
    DataInputStream input;
   byte [] message;
    
    public Cliente(){
        
        super("Socket Cliente");
        Container c = getContentPane();
        enter = new JTextField();
        enter.setEnabled(true);
        enter.addActionListener( 
                new ActionListener(){ 
                    public void actionPerformed(ActionEvent e){
                        
                        if (!enter.getText().equals(null))
                        sendData(e.getActionCommand());
                                        }
                                }           
                               );
        c.add(enter,BorderLayout.NORTH);
        display = new JTextArea();
        c.add(new JScrollPane(display), BorderLayout.CENTER);
        setSize(300,150);
        setVisible(true);
        enter.requestFocus();
                    }
    
     
    
    public String byteToString(byte[] parametro){
            
            String resultado = "";
            
            for (int i = 0; i < parametro.length; i++){
                
                if (parametro[i] < 0 )
                     
                    resultado = resultado + (Integer.toHexString(256+parametro[i]).toUpperCase());
                
                if (parametro[i] < 16){
                    
                    resultado += "0";
                    resultado += (Integer.toHexString(parametro[i]).toUpperCase());
                    
                    
                }
            }
            
           return resultado;
            
        }
    

     
    
    
    
    private void sendData(String data){
        
        try{
            
            Socket client;
            String host = "192.168.0.52";
            int porta = 11010;
            display.setText("Tentando a conexão \n");
            client = new Socket(InetAddress.getByName(host),porta);
            display.append("Conectado em: " + client.getInetAddress());
            output = new DataOutputStream(client.getOutputStream());
            output.flush();
            input = new DataInputStream(client.getInputStream());
            display.append("\n Adquirindo I/O streams ");
        
            enter.requestFocus();
            
            
            byte[] b = new byte[data.length() / 2];

                try {
                    String s1;

                        int j=0;
                             for(int i = 0; i < data.length(); i += 2)
                                {
                                    s1 = data.substring(i, i + 2);
                                    b[j] = (byte)Integer.parseInt(s1, 16);
                                     j++;
                                  }
                         } 
                                catch(NumberFormatException ex)  {
                                     ex.printStackTrace();
                                  } 
                                catch(StringIndexOutOfBoundsException ex){
                                           ex.printStackTrace();
                                  }
             
            
                        
                           
                          
                             
                             output.write(b);
                             output.flush();
                             System.out.println("Aqui");
                             input.readFully(b) ;
                             
                             message = b;
                             output.close();
                             input.close();
                             client.close();
                             enter.setText(null);
                           //  for(int i = 0 ; i< u.length ; i++)
                             System.out.print("|"+ byteToString(u));
                             display.append("\nILV enviado: " + data);
                             
                             
                             display.append("\n ILV recebido: " + byteToString(message));
                             
                    }
        
               catch(IOException op){
                    display.append("\n Erro ao escrever o objeto.");
               }
        
        }
        
        
        
        
    
        public static void main(String Args[]){
            
            Cliente app = new Cliente();
            app.addWindowListener(
                    new WindowAdapter(){
            @Override
                        public void windowClosing(WindowEvent e){
                            System.exit(0);
                        }
            }
                    
                    );
                    
             
             
        }


}

O codigo é esse e ele funciona perfeitamente com comandos que a resposta é do mesmo tamanho que o envio, se for diferente tenho que istanciar outro array para leitura, o problema é que nem sempre sei o tamnho do array de resposta...
como por exemplo listar todas as bases de dados, o array pode vir de n maneiras ... alguma solução??

V

Perguntei sobre o protocolo da leitora, não sobre o protocolo de transmissão de dados.

Quando vc envia um comando, (como esse que vc citou) como é o formato de retorno? Baseado em texto? Binário? Tem algum terminador, como \n \0?

P

A entao
o retorno é um array de bytes, e nao tem terminador de inicio ao fim sao bytes

V

E como vc interpreta esse retorno?

P

Eu tenho um tabelinha com possiveis respostas por exemplo se eu pingo a leitora com {0x08,0x00,0x00} a resposta devera ser
id_ comando, lenght_comando, request_status = {0x08,0x01,0x00} , porem em comandos por exemplo pra listar em que diretorio esta tal arquivo a sequencia em bytes ascii pode variar e não vejo maneiras de como istanciar o array de resposta para tal, só na tentativa e erro…

V

Ué, o campo length_comando não informa o tamanho contando os arrays?

P

entao, mas para ver o campo lenght primeiro eu precizo instanciar o vetor para guardar a resposta completa

V

Não, se suas mensagens sempre começam por:
id_ comando, lenght_comando

Você tem que ter 2 variáveis para esses 2 valores. Faça a leitura delas separadamente.
Depois de ler o length, você então cria o vetor, e lê o resto.

P

Sim, mas como farei isso, teria que abrir e fechar o socket 3 vezes para paegar toda resposta?
ou a outra maneira, pois qdo dou input.read(byte[],inicio,qtd_bytes) mais de uma vez a segunda resposta só vem bytes nulos, tentei o metodo reset() mais nem deu, tem alguma outra maneira??

P

Há o id do comando , o tamanho e a resposta, vem no mesmo array de bytes.

V

Antes do seu read, faça outros dois reads... Não precisa fechar o socket entre as leituras.

int idComando = input.read();

//Os dois primeiros bytes  foram lidos
int len = input.read() - 2;

byte[] buffer = new byte[len];
input.read(buffer,inicio,len)

Se cada valor desses tem mais de 2 bytes, faça as contas de acordo, e use o read apropriado. Use para isso o DataInputStream.

A questão é que você sabe que sempre antes dos arrays haverá esses dois campos. Por isso, faça a leitura deles separadamente. A informação de um deles te permite ler a parte variável com segurança.

P

Certo, resolvido…
vlw Vinii

Criado 15 de outubro de 2009
Ultima resposta 20 de out. de 2009
Respostas 14
Participantes 3