[Conceito/Desafio] - Protocolos de Rede
Published: 2023-02-07 04:48:12

> Conteúdo original em https://twitter.com/zanfranceschi/status/1622817858219814913

---

Ei dev,

Bora criar um protocolo de comunicação de rede usando sockets?

Apesar de geralmente ser ineficiente em contextos profissionais, "inventar moda" pode ser um método genuíno e lúdico de aprendizado.

Cola mais se tiver curiosidade sobre o assunto!

cc @sseraphini

↓

![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1gkln8o6k2tlkg6ce33e.png)

---

Disclaimer: existem milhares de protocolos de rede e esse desafio não tem o objetivo de ensinar detalhes e melhores práticas sobre a elaboração de um protocolo de comunicação. O intuito aqui é te expor a componentes de mais baixo nível de rede e exercitar a criatividade. Fechado?

---

Bom, vamos criar um problema pra inventar a nossa solução 🤭

Vamos criar o REDIS VERSÃO XGH – A última geração de in-memory key/value store! 🐴 👀

Nessa versão, pra simplificar, a gente deve ser capaz de definir e ler (SET e GET) um item (key/value pair). E só.

---

O Redis, pra quem não sabe, é principalmente um banco in-memory NoSQL que armazena chaves e valores (key/value pairs). Simplificando muito, é um dicionário em memória de alta performance.

---

Agora vamos ao nosso protocolo!

Sugiro ser um protocolo textual, como por exemplo o HTTP ou até mesmo o protocolo do REDIS de verdade, o RESP.

Protocolos textuais são mais amigáveis para se lidar apesar de ocuparem mais espaço.

https://redis.io/docs/reference/protocol-spec/

---

ESPECIFICAÇÕES:

- 5 primeiros caracteres: tamanho do restante da mensagem (sem contar esses 5).

- 3 próximos caracteres: "GET" ou "SET".

- 15 próximos caracteres: nome da chave a ser lida (GET) ou definida (SET).

- Restante dos caracteres (apenas para "SET"): valor da chave.

![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v9u8h9vgmxw1p669gs4j.png)

---

Note que os 5 primeiros caracteres funcionam como uma espécie de header que indica o tamanho do conteúdo. Fazendo uma analogia, é o Content-Length do HTTP.

Para as chaves, limitamos o tamanho para até 15 caracteres. Já o valor da chave pode ser de até 99.981 (99.999 - 18) bytes.

---

Agora é a vez de falarmos sobre sockets que são componentes de rede baixo nível. Já mexi com sockets em algumas linguagens diferentes e todas têm uma API muito parecida. Portanto, os exemplos em Python usados aqui devem te dar um norte na sua lang preferida.

---

Esse exemplo em Python deve te dar uma ideia sobre as partes fundamentais do uso de sockets do servidor – o nosso Redis caseiro.

![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/he6ig86kuc6rbus9y19g.png)

---

Note que nos códigos de exemplo, não há a implementação da interpretação das mensagens (se é GET, SET, tratamento de erros, etc.). Isso é com você!

Esse próximo exemplo, mostra algumas partes fundamentais do cliente – a aplicação quer irá usar o nosso Redis caseiro.

![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l6u4u570ff8kdt3l5br5.png)

---

Poxa, nosso protocolo tem uma falha: não há especificação das respostas! E a implementação do nosso cliente que simplesmente lê 1024 bytes? E se a mensagem for maior?

Bem, agora é com você especificar as respostas do nosso protocolo de rede e implementá-lo certinho, blz?

---

amos falar rapidamente de alguns conceitos relacionados.

Os exemplos aqui usam TCP/IP (note a definição dos sockets nos códigos).

TCP é um protocolo de fluxo (stream), centrado em conexão. Ou seja, a conexão, que é bidirecional, fica aberta até que alguém a encerre.

---

Deu pra notar que no exemplo a gente encerra a conexão no server depois de ter lido N bytes indicados no conteúdo, né?

Uma alternativa seria encerrar a conexão depois de ter lido uma quebra de linha ou outro caracter também, por exemplo. Ou simplesmente manter a conexão aberta!

---

Já numa conexão UDP, que não é centrada em conexão – connectionless protocol –, você simplesmente envia a mensagem pro destino e (teoricamente) dá bom.

---

Outro aspecto que vale mencionar é que escolhemos fazer um protocolo textual.

"Mas a gente não transforma tudo em bytes pra enviar?" você pergunta. Sim!

Um protocolo ser binário ou textual não está relacionado à representação dele na rede – está relacionado a sua estrutura.

---

Um protocolo textual, como o HTTP, é amigável para humanos, fácil de ler. Já um protocolo binário, geralmente implica em termos que nos basear nas especificações para entendê-lo. Octeto pra lá e pra cá – afe.

---

Protocolos binários geralmente são elaborados com performance de processamento e restrições de espaço em mente. São computacionalmente mais eficientes.

Já protocolos textuais são computacionalmente menos eficientes, mas o design para quem o usa é mais amigável.

---

Novamente, design de protocolos é um assunto super vasto e naturalmente existe muito mais coisa do que abordei aqui.

Como disse anteriormente, esse desafio foi só para que você crie um intuição de como um protocolo pode funcionar num nível muito elementar.

---

Se você leu até aqui, meus sinceros agradecimentos – você é uma pessoa realmente nerd pra ler esse tipo de coisa no Twitter ou muito perdida e/ou desocupada se não for ou tiver interesse na área! ❤️