# Datagram sockets

Utilizando `netcat`, podemos criar um socket UNIX no formato **datagram**, que é um formato simples de mensagem, enviada em pedaços via sistema de arquivos.

```bash
## Server
$ nc -Uulv /tmp/queue.sock
Bound on /tmp/queue.sock
```

Vamos entender as opções do comando `nc`:

* `-U`: cria um UNIX socket
* `-u`: as mensagens no socket são do tipo datagram
* `-l`: atribui um file descriptor ao arquivo `queue.sock`
* `-v`: modo verboso, mostra quaisquer erros e outras saída no STDOUT

Com isto, o processo *server* está pronto a receber mensagens no socket. Agora, em **outra sessão**, enviamos mensagem para o socket, tal como fizemos com named pipes:

```bash
$ echo PING > /tmp/queue.sock
bash: /tmp/queue.sock: No such device or address
```

Uh, oh...*por quê este erro?*&#x20;

Quando o socket é iniciado, lhe é atribuído um *file descriptor* para envio de mensagens. Entretanto, como socket atua na camada de rede, é criado através de um *dispositivo*, ou **device**. Tal dispositivo está associado ao file descriptor, portanto não devemos enviar a mensagem para o arquivo do socket, mas para o **file descriptor** atribuído ao **processo que iniciou** o socket., ou seja, o **server.**&#x20;

Já sabemos como enviar redirecionar mensagem a um fd através de redirecionamento de streams, mas para o fd do reader precisamos saber o *identificador do processo*, ou **PID.**&#x20;

Com o comando `ps -C [program]`, conseguimos saber o processo que está rodando o programa `nc`, e com a opção `-o pid=`, é mostrado no output apenas o PID do processo:

```bash
$ ps -C nc -o pid=
1022
```

Okay, com o PID em mãos, onde está o *file descriptor*?&#x20;

Geralmente, em distribuição *Ubuntu*, o caminho para o **fd** associado ao STDIN do processo é `/proc/[pid]/fd/0`, lembrando que STDIN é sempre associado ao `fd 1` para qualquer processo UNIX.

```bash
$ echo PING > /proc/1022/fd/1
```

Um exemplo da funcionalidade completa:

<figure><img src="/files/ttK73cfiDc6SCCy7P47W" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/JgNBEwfcS5uRofLFlbsu" alt=""><figcaption></figcaption></figure>

#### Full-duplex

Okay, mas toda esta comunicação com socket ainda está uni-direcional, ou seja, a informação caminha do writer para o reader, e não faz o caminho inverso.&#x20;

<figure><img src="/files/L3PhI42PlkuwUABsfuN8" alt=""><figcaption></figcaption></figure>

Isto porque precisamos de outro arquivo de socket para receber a mensagem de volta do reader, tal como fizemos no exemplo com 2 named pipes (FIFO) para comunicação **bi-direcional.**

Hoje é nosso dia de sorte, o comando `nc` permite criar um arquivo de socket a partir de outro já existente:

```bash
$ nc -Uuv /tmp/queue.sock
Bound on /tmp/nc.XXXXPRdYP5
```

Note a mensagem `Bound on /tmp/nc.XXXXPRdYP5`, que significa que o programa `nc` criou outro socket para o client, associando-o ao socket do server. Desta forma, podemos ter uma comunicação **full-duplex** com UNIX sockets.

* **Client socket**: /tmp/nc.XXXXPRdYP5
* **Server socket**: /tmp/queue.sock

<figure><img src="/files/FIQ1KrRuGdVtOOluClQP" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/36C7l94VHXoaSI1dB84r" alt=""><figcaption></figcaption></figure>

### Considerações sobre datagram sockets

Há alguns pontos que devemos considerar quando utilizamos datagram sockets:

* não há garantia de que a mensagem chega na ordem correta, pode ser que pedaços da mensagem sejam enviados de forma desordenada
* não há garantia que todos os pedaços da mensagem sejam entregues de todo

Quando a consistência da mensagem importa, devemos utilizar outro tipo de socket, o **stream socket,** que será assunto da próxima seçã&#x6F;**.**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://web101.leandronsp.com/comunicacao-entre-processos/unix-sockets/datagram-sockets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
