TCP Sockets

TCP, ou Transmission Control Protocol, é uma abstração de stream sockets na camada TCP/IP da Internet. Por se no formato stream, há a garantia de entrega da mensagem na ordem correta.

Assim como UNIX sockets, também podemos criar TCP sockets com netcat. Inclusive o padrão do netcat é TCP, portanto basta removermos a opção -U dos exemplos que criamos anteriormente e pronto, temos um socket TCP.

## Server
$ nc -lv /tmp/server.sock
nc: getaddrinfo: Servname not supported for ai_socktype

Uh, oh...não conseguimos criar o server no socket server.sock com TCP.

Para entender este erro, vamos primeiro simular como seria um cliente remoto, ou seja, em outro computador, conectando neste socket.

Ps: para efeitos didáticos, vamos fazer todos os exemplos no mesmo computador. Com TCP funciona na mesma, é como se tivéssemos em computadores diferentes.

## Client
$ nc -v /tmp/server.sock
nc: missing port number

Vamos por ora ignorar a mensagem de erro. Repare o problema neste comando. O cliente precisa saber o caminho do socket no servidor remoto. Isto pode trazer problemas de segurança graves, pois um cliente conhecer o caminho do socket abre caminhos para possíveis ataques ao servidor.

Por isto é obrigatório que o client informe o número da porta. Mas que porta? O quê é uma porta neste contexto de TCP/networking?

Portas de rede

Porta é um conceito em redes de computadores que permite abstrair o caminho de um socket, mais precisamente de um processo em execução no sistema operacional.

A forma que uma porta é associada e um processo é através de um conceito parecido com file descriptors, que são socket descriptors.

Conexão cliente-servidor

Como agora sabemos que um socket TCP precisa do número da porta, basta iniciarmos o comando netcat com o número de uma porta que não esteja sendo utilizada, ao invés do nome do socket.

## Server
$ nc -lv 8080
Listening on 0.0.0.0 8080
  • -l: o server ficará à escuta de conexões na porta 8080

  • -v: modo verboso

Nice! Temos um TCP socket rodando na porta 8080 do computador. E como podemos confirmar isto? Com o comando lsof:

$ lsof -i tcp:3000
COMMAND  PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
nc      1113 root    3u  IPv4 7228577      0t0  TCP *:8080 (LISTEN)

Podemos ver que o comando nc, de PID 1113, está no modo LISTEN TCP na porta 8080.

Agora, vamos ao lado do cliente:

## Client
$ nc -v localhost 8080
Connection to localhost (127.0.0.1) 8080 port [tcp/*] succeeded!

Note que o comando nc, caso seja utilizado como client, precisa informar 2 argumentos:

  1. endereço do server, neste caso, utilizamos o próprio localhost mas poderia ser qualquer IP público da rede

  2. número da porta onde o server está à escuta, neste caso, 8080

Na interação acima, repare que assim que o cliente conecta no server, é mostrada a mensagem Connection received on localhost 46216.

Isto porque, pela característica full-duplex como vimos com 2 named pipes e UNIX sockets, os sockets TCP também estabelecem outro socket para leitura do cliente, neste caso, outra porta de rede.

Inclusive dá pra confirmar verificando todos os processos interagindo com a porta 8080:

$ lsof -i tcp:8080
COMMAND  PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
nc      1280 root    3u  IPv4 7280841      0t0  TCP *:8080 (LISTEN)
nc      1280 root    4u  IPv4 7280100      0t0  TCP localhost:8080->localhost:46216 (ESTABLISHED)
nc      1283 root    3u  IPv4 7280954      0t0  TCP localhost:46216->localhost:8080 (ESTABLISHED)

Com isto, podemos concluir que:

  • há um file descriptor (3u) criado para o socket do server e também as mensagens dentro da conexão TCP que o cliente envia para o server, da porta 46216 para a porta 8080

  • há outro file descriptor (4u) para representar as mensagens dentro da conexão TCP que o server envia de volta para o cliente, da porta 8080 para a porta 46216

É tudo sobre file descriptors!

Resumo

Esta seção apresentou a funcionalidade de TCP sockets, bem como sua similaridade com UNIX stream sockets.

A seguir, vamos explorar como trabalhar com sockets de internet que utilizam datagram, os sockets UDP.

Last updated