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.

## 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:

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

Uh, oh...por quê este erro?

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.

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.

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:

$ ps -C nc -o pid=
1022

Okay, com o PID em mãos, onde está o file descriptor?

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.

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

Um exemplo da funcionalidade completa:

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.

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:

$ 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

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ção.

Last updated