Como criar um protocolo

Oi.
eu estou querendo criar um protocolo em java que envie um array de bytes mas não estou conseguindo fazer.
eu queria pegar por exemplo:

[header][tamanho][telefone][endereco][cpf]
AB000000101141367733Alameda das32645654654

Onde os campos header, tamanho, telefone, endereço e cpf seriam tags para identificação e cada campo teria um tamanho determinado.Eu iria pegar esta informação(AB000000101141367733Alameda das32645654654) colocar em bytes e mandar através de um socket e pegaria do outro lado e faria a engenharia reversa.
Alguma ideia de como fazer tal proeza ?

Olá,

Tu já manjou como é que faz a transmissão com TCP? Esse é o primeiro passo.

Depois, você só precisa criar duas classes, um codificador e um decodificador. O primeiro vai serializar os dados para serem enviados pelo socket, e o segundo vai decodificar a mensagem, ler esses headers e montar o objeto com os dados.

1 curtida

Um vez eu criei um programa para enviar dados por Socket. Eu consegui inclusive fazer Streaming de vídeo por Socket, mas é um projeto bem antigo. Eu consegui extrair do código algo que pode te ajudar.

 public void go() {
        try {
            serverSock = new ServerSocket(4242);
                		 while (!serverSock.isClosed()){
                             ObjectOutputStream output = null;
							try {
								clienteSocket = serverSock.accept();
								output = new ObjectOutputStream(clienteSocket.getOutputStream());
								ArrayList<String> lista = new ArrayList<String>();
								lista.add(System.getProperty("os.arch"));
								lista.add(System.getProperty("os.name"));
								lista.add(System.getProperty("os.version"));
								lista.add(System.getProperty("user.name"));
								lista.add(System.getProperty("user.home"));
								output.writeObject(lista);
								output.flush();
							} catch (IOException e1) {
								e1.printStackTrace();
							}
    }

E como visto ali, qualquer objeto serializado pode ser enviado através do método writeObject.

E lido também…

			Outretorno = new ObjectInputStream(client.getInputStream());
			ArrayList<String> informacoes = ((ArrayList<String>) Outretorno.readObject());
			String arc = informacoes.get(0);
			System.out.println(arc);
			String osName = informacoes.get(1);
			System.out.println(osName);
			String osVersion = informacoes.get(2);
			System.out.println(osVersion);
			String userName = informacoes.get(3);
			System.out.println(userName);
			String userHome = informacoes.get(4);
			System.out.println(userHome);

essa parte eu sei, mas a duvida é em como eu iria criar o protocolo como eu disse q a classe receba:
AB000000101141367733Alameda das32645654654 e saiba o significado disso e quebre este array de forma certa

Aí depende totalmente de como você quer fazer. É criatividade pura aqui.

A abordagem mais fácil é delimitar o tamanho da mensagem e preencher os espaços vazios com zero. Porém, dessa forma, você tem duas desvantagens: quando a mensagem for menor do que o tamanho fixado, você vai gastar mais banda do que é necessário. Quando a mensagem for maior do que o tamanho fixado, você vai ter que mandar mais de uma mensagem.

Outra maneira é delimitar apenas o tamanho do cabeçalho da mensagem, e nele colocar metadados sobre a mensagem, como você falou ali, incluindo o tamanho da mensagem que vai chegar.

Você tem que criar a definição de como os dados serão transmitidos, isso que é criar um protocolo da camada de aplicação.

Um exemplo é o protocolo HTTP, que se baseia em quebras de linhas para interpretar a mensagem. Se eu não me engano, a quebra de linha do HTTP é \r\n. Olhe aqui a descrição da requisição do protocolo HTTP: https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html

1 curtida

No meu caso o usuário ia preencher uma jtabel que possui duas colunas: Tipo e valor.
eu estou tentando pegar os valores digitados na coluna tipo e fazer o cabeçalho, e com os dados digitados na coluna valor usar para preencher o protocolo.
Mas basicamente eu queria pegar todas as informações concatenar tudo junto em um ArrayList por exemplo e mandar para a classe de decodificação, usar os dados e depois usar a classes de codificação para montar o protocolo novamente e enviar a resposta

Que tal colocar uma espécie de tag ao redor da tua mensagem serializada? Algo como:

__comeco__..........__fim__

Ou então utilizar um formato pronto, como XML ou JSON.

2 curtidas

não existe nenhum método em java que faça tal proeza ?

eu estava pensando em usar arraysLIst um dentro do outro para fazer isso, mas poderíamos considerar isso como uma “gambiarra” :sweat_smile: