Rede de Computadores

Uma introdução a TCP, UDP e Sockets

A ideia desse artigo é introduzir o essencial para desenvolvedores que desejam compreender sockets. O foco estará na parte teórica, que servirá de base para outros artigos que lidarão com a parte prática da programação com sockets.

A rede de computadores

Uma rede de computadores caracteriza-se por dois ou mais computadores interligados, não importando por qual meio (cabos, ondas de rádio etc), desde que sejam capazes de trocar informações entre si e/ou compartilhar seus recursos de hardware.

Em uma rede de computadores também podemos ter clientes e servidores. Servidor é uma máquina que fornece um serviço qualquer na rede e Cliente é uma máquina que consome o serviço fornecido pelo Servidor. Também dizemos que algumas aplicações são clientes e outras servidoras, quando fornecem ou consomem serviços na rede. Por exemplo, o Mozilla Thunderbird é um cliente de e-mail, já o Postfix é um servidor de e-mail. Um navegador de internet (Chrome, Firefox etc) é uma aplicação cliente que requisita dados de um servidor.

Uma rede funciona sob protocolos (que são regras que definem o funcionamento dela) e a família de protocolos mais conhecida e utilizada é a TCP/IP, que engloba os protocolos IP (da camada de rede), TCP e UDP (da camada de transporte), HTTP (da camada de aplicação) entre outros.

A referência de como as redes funcionam e são construídas vem do modelo OSI, que foi definido pela ISO em meados dos anos 80 para servir de referência para o projeto de hardware e software das redes, pois o que acontecia é que cada fornecedor implementava o seu próprio padrão e isso prejudicava a interoperabilidade. Apesar do modelo OSI ainda ser a referência teórica (o modelo) para as redes, a arquitetura TCP/IP é que tem a aplicabilidade e o protagonismo nas intranets e na internet.

O modelo OSI possui sete camadas enquanto o TCP/IP é dividido em cinco. O diagrama abaixo mostra onde as camadas do modelo TCP/IP se “encaixam” no OSI:

O protocolo IP (Internet Protocol) é o mais importante da família TCP/IP (ele se localiza na camada de rede) e ele deve ser associado com outros protocolos e, no contexto desse artigo, os mais importantes e mais utilizados são o TCP e o UDP.

TCP vs UDP

Ambos são protocolos da camada de transporte e, quando precisamos de confiabilidade no transporte do dado, usamos o protocolo IP associado ao TCP (que garante a entrega das informações). Quando priorizamos mais velocidade e menos controle, associamos o protocolo IP ao UDP (tráfego de voz e vídeo são bons exemplos onde o UDP teria boa aplicabilidade, ademais, perdendo um ou outro pacote, não interfere totalmente no todo, permanecendo inteligível).

Observe que a comunicação no TCP se dá nas duas pontas:

Algumas das principais características do TCP (Transmission Control Protocol):

  • Orientado à conexão (só transmite dados se uma conexão for estabelecida depois de um Three-way Handshake);
  • É Full-duplex, ou seja, permite que as duas máquinas envolvidas transmitam e recebam ao mesmo tempo;
  • Garante a entrega, sequência (os dados são entregues de forma ordenada), não duplicação e não corrompimento;
  • Automaticamente divide as informações em pequenos pacotes;
  • Garante equilíbrio no envio dos dados (para não causar “sobrecarga” na comunicação);

No UDP, a comunicação se dá em uma ponta e, se algum segmento falha, isso é ignorado e o fluxo continua:

Algumas das principais características do UDP (User Datagram Protocol):

  • Diferente do TCP ele não é orientado à conexão;
  • Não é confiável como o TCP, ele não garante a entrega completa dos dados;
  • É preciso que dividamos manualmente os dados em datagramas (entidades de dados);
  • Não garante a sequência da entrega, portanto, os dados podem chegar em uma ordem aleatória;

Por essas características menos restritivas (menos controles) ele é muito mais rápido que o TCP. Como contrapartida, ele exige um pouco mais do desenvolvedor na hora de implementá-lo.

Por fim, é importante pontuar que tanto o UDP quanto o TCP trabalham com portas, que são elementos lógicos que interligam clientes e servidores de aplicações em redes TCP/IP. O cliente precisa saber qual porta ele se conectará no servidor. Por exemplo, servidores web por padrão usam a porta 80 para servir as páginas e quando acessamos uma página web usando o protocolo http (que é um protocolo de aplicação da TCP/IP) uma conexão TCP à porta 80 do servidor é feita.

Administrador de redes Júnior
Formação: Administrador de redes Júnior
Nesta formação, você verificará os princípios essenciais para um administrador de redes: os fundamentos de uma rede de computadores (LANs, PANs, WANs, sistema binário e o modelo OSI), o funcionamento completo de ponta-a-ponta do protocolo TCP/IP e as estruturas essenciais para operações de routing e switching (os protocolos CDP, LLDP e LACP, além de tabelas de roteamento, ,protocolos OSPF e RIP e o algoritmo Spanning Tree).
CONHEÇA A FORMAÇÃO

O que é um Socket?

Socket provê a comunicação entre duas pontas (fonte e destino) – também conhecido como two-way communication – entre dois processos que estejam na mesma máquina (Unix Socket) ou na rede (TCP/IP Sockets). Na rede, a representação de um socket se dá por ip:porta, por exemplo: 127.0.0.1:4477 (IPv4). Um socket que usa rede é um Socket TCP/IP.

Muito do que fazemos no dia a dia faz uso de sockets. O nosso navegador utiliza sockets para requisitar as páginas; quando acessamos o nosso servidor pelo protocolo de aplicação SSH também estamos abrindo e utilizando um socket.

Sabendo que TCP/IP é base da nossa comunicação na internet, considerando o modelo de rede OSI, os sockets estão entre a camada de aplicação e a de transporte:

Para os processos envolvidos a sensação é que a comunicação está acontecendo diretamente entre eles, no entanto, ela está passando pelas camadas da rede. Essa abstração provida pelos Sockets é o que chamamos de comunicação lógica. Outra forma de entender os Sockets é que eles são a “interface” de comunicação interprocessos.

Todo cliente deve conhecer o socket do servidor (conjunto ip e porta) para se comunicar, mas o servidor só vai conhecer o socket do cliente quando este realizar uma conexão com ele, ou seja, a conexão no modelo cliente-servidor é sempre iniciada pelo cliente.

O diagrama abaixo mostra que a porta do servidor precisa ser previamente conhecida pelo cliente, enquanto que pro servidor não importa qual é a porta do cliente, ele vai conhecê-la quando a conexão dele com o cliente for estabelecida.

Sistemas operacionais baseados no Unix proveem uma interface padrão para operações I/O (input e output) que se passa por descritores de arquivo. Um descritor de arquivo é representado por um número inteiro que se associa a um arquivo aberto e, nesses sistemas, há uma generalização de que “tudo é um arquivo”, então, nesse contexto, um arquivo pode ser uma conexão de rede (um socket é um tipo especial de arquivo), um arquivo de texto, um arquivo de áudio, até mesmo uma pasta é um tipo especial de arquivo.

Como um socket se comporta como um arquivo, chamadas de sistema de leitura e escrita são aplicáveis, da mesma forma como funcionam em um arquivo ordinário, e é aqui que entra a programação de sockets com a API POSIX sockets. Linguagens como o Java, PHP etc, abstraem isso fornecendo ao desenvolvedor uma API de ainda mais alto nível.

Unix Socket

Em sistemas Unix e agora recentemente também no Windows 10, temos um mecanismo para a comunicação entre processos que estão no mesmo host (ao invés da rede), chamado de Unix Socket. A diferença entre um Unix Socket (IPC Socket) de um TCP/IP Socket é que o primeiro permite a comunicação entre processos que estão na mesma máquina. Já o segundo, além disso, permite a comunicação entre processos através da rede.

No entanto, um TCP/IP Socket também pode ser usado para a comunicação de processos que estão na mesma máquina através do loopback que é uma interface virtual de rede que permite que um cliente e um servidor no mesmo host se comuniquem (em IPv4 através do IP 127.0.0.0).

A particularidade é que Unix Sockets estão sujeitos às permissões do sistema e costumam ser um pouco mais performáticos, pois não precisam realizar algumas checagens e operações, por exemplo, de roteamento, algo que acontece com os TCP/IP Sockets. Ou seja, se os processos estão na mesma máquina, Unix Sockets podem ser a melhor opção, mas se estiverem distribuídos na rede, os TCP/IP Sockets são a escolha certa.

Se você tem acesso a algum servidor baseado em Unix, execute netstat -a -p --unix que ele listará todos os Unix Sockets abertos no sistema operacional (bem como mostrará outras informações como o tipo do Socket, caminho etc). Se você quiser visualizar tanto os TCP/IP Sockets quanto os Unix Sockets, você pode executar netstat -na, ele exibirá duas tabelas listando todos os sockets abertos:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 127.0.0.1:9070          0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:9072          0.0.0.0:*               LISTEN

...

Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node   Path
unix  2      [ ]         DGRAM                    26007836 /run/user/1000/systemd/notify
unix  2      [ ACC ]     SEQPACKET  LISTENING     1976     /run/udev/control

...

Existem quatro tipos de sockets: Stream Sockets, Datagram Sockets, Raw Sockets e Sequenced Packet Sockets sendo que os dois primeiros são os mais comuns e utilizados.

  • Stream Sockets (SOCK_STREAM): Esse tipo usa TCP, portanto, todas as características enumeradas anteriormente se aplicam a ele: garantia de entrega e ordem, orientado à conexão etc;
  • Datagram Sockets (SOCK_DGRAM): Esse tipo usa UDP, portanto, não é orientado à conexão, não garante entrega completa dos dados e exige um controle mais especial do desenvolvedor.

Concluindo

Sockets estão presentes em quase tudo o que fazemos na internet, naquele jogo multiplayer que você joga, naquele chat que você iniciou online e muito mais. As linguagens de programação (ou extensões delas) abstraem grande parte da programação com sockets. Espero que esse artigo te incentive a trabalhar/estudar um pouco mais sobre eles usando a sua linguagem favorita.

Recomendação de leitura

Se você programa ou tem interesse por PHP: Programação de Sockets em PHP.