Share

Introdução

Neste artigo, Programação de Sockets para Linux, você terá uma introdução a um assunto de grande importância para conectividade entre equipamentos através de protocolos de comunicação.

Atualmente muitos softwares precisam se conectar à internet para realizar alguma tarefa específica. Conectividade é um assunto muito importante hoje em dia, ela se tornou praticamente obrigatória no desenvolvimento de novos aplicativos. Muitos negócios, em hoje em dia, dependem da internet para funcionarem, isso tem se tornado em algo gigantesco que gera muito dinheiro para diversas empresas. Pode-se citar, por exemplo, vídeo games online que faturam mais que filmes de Hollywood, como o World of Warcraft que já faturou mais de $10 bilhões. Mas isso não se limita apenas à jogos, obviamente. Para muitas aplicações a conectividade é muito importante.

O que torna o conexão à internet possível, no caso dos softwares, são os sockets. Em termos simples, socket é um arquivo que representa uma conexão entre dois processos distintos, que podem estar no mesmo sistema ou não, através de um canal de transmissão. Para que a comunicação entre sockets funcione existem uma série de padrões e protocolos de comunicação. A internet que usamos no dia a dia usa a arquitetura TCP/IP. Essa arquitetura é dividida basicamente em cinco camadas. Os sockets estão no 4 nível do TCP/IP, especificamente na camada de transporte.

A arquitetura TCP/IP

TCP Modelo OSI

A arquitetura TCP/IP apresenta cinco camadas, enquanto que o modelo de referência OSI usa 7 camadas. Cada camada tem um função especifica e bem definida. Abaixo é dado de forma resumida a função de cada camada no modelo OSI.

Nível de Aplicação

Possui um conjunto de protocolos diversificado e orientado à aplicações bem definido. Exemplos: FTP, SNMP, DNS, HTTP, etc.

Nivel de Apresentação

Representação dos dados. Realiza transformações adequadas nos dados (compressão de textos, criptografia, etc). Seleção de sintaxes dos dados. Deve-se conhecer a sintaxe do sistema local e do sistema de transferência.

Nível de Sessão

Permite a comunicação com sucesso entre as aplicações. Controle de diálogo ( em caso de interrupção, a rede continua de onde parou). Gerenciamento de atividades (prioridades). Sincronização.

nível de Transporte

Isola a parte de transmissão da rede dos níveis superiores. Controle de sequência fim-a-fim. Controle de congestionamento. Detectação e recuperação de erros fim-a-fim

nível de Rede

Unidade de dados/pacotes. Roteamento de pacotes. Fragmentação e remontagem de pacotes. Conversão de endereços lógicos em endereços físicos. Não garante a entrega dos pacotes ou a sequência correta entre eles.

Enlace de Dados

Detecta e corrige erros ocorridos no nível físico. Converte um canal de transmissão não confiável em um canal confiável. Enquadramento de cadeias de bits. Redundância para detecção de erros (bits de controle e retransmissão). Controle de acesso.

Física

Fornece características mecânicas, elétricas e funcionais para ativar, manter e desativar conexões físicas para transmissão de bits. Define o padrão de sinalização com o meio físico. Não trata erros de transmissão! Em resumo, converte quadros em sinais elétricos para serem transmitidos através do cabo de rede ou outro de meio de transmissão qualquer.

O que são Sockets

O estabelecimento de conexão entre processos diferentes é feito através de um socket. Através dele é possível acessar protocolos da camada de transporte, como TCP e UDP. Sockets garantem a intercomunicação bidirecional entre processos, executados localmente ou em máquinas conectadas através de uma LAN/WAN.

A comunicação entre sockets é feita por meio de um endereçamento. A formação dos endereços vai depender do domínio. Alguns exemplos de domínios de sockets:

  1. AF_UNIX – endereço é composto por um caminho dentro do sistema de arquivos. O domínio está restrito a árvore de diretórios acessível pelo processo que criou o socket. Utilizado quando os processos rodam em uma mesma máquina;
  2. AF_INET – O endereço é composto pelo endereço de rede da máquina (IP) e o número de identificação da porta sendo utilizada pelo processo. Este é o mais comumente usado

Tipos de sockets:

  1. SOCK_STREAM – indica que os dados irão trafegar pelo socket na forma de um stream de caracteres.
  2. SOCK_DGRAM – indica que os dados irão trafegar pelo socket na forma de datagramas.
  3. SOCK_RAW – um socket raw é um socket que permite o envio direto e recebimento de pacotes de Protocolo de Internet sem qualquer formatação específica da camada de transporte. Ele é muito usado por hackers para implementação de algumas técnicas de ataque.

API para desenvolvimento de sockets

Todo sistema operacional atual tem sua implementação do padrão TCP/IP, tanto para uso interno, como para o uso em software através de uma API. A API vai nos permitir criar um socket, envia dados pela rede, receber dados do mundo externo, “escutar” em uma porta à espera de conexões, etc. Cada sistema operacional que suporta rede tem algum tipo de Stack de rede. Linux não é exceção. A pilha de rede é o que permite que os aplicativos sejam capazes de acessar a rede por meio de um dispositivo de rede física. Dispositivos de rede pode ser modems, cable modems, ISDN, dispositivos Wi-Fi, placas Ethernet, placas Token Ring, etc. Em adição a isso, o Linux já suporta o protocolo IPv6.

Para que a conexão seja estabelecida, algum processo no sistema operacional precisa “tomar iniciativa” e iniciar o processo de conexão. Dessa forma, será haverá o processo cliente e o processo servidor. O cliente é processo responsável por abrir uma conexão, ou socket, em uma determinada porta. O servidor é o processo responsável por esperar uma conexão em uma determinada porta, associada a um certo serviço. Existem várias formas e abordagens de programar um software cliente e um software servidor. Vamos abordar a implementação através de threads.

A API de sockets disponibilizada pelo Linux, ou o Windows, tem funções que seguem o padrão de sockets BSD, também conhecido como Berkeley sockets. O API de sockets BSD é escrito na linguagem de programação C. A maioria das outras linguagens de programação oferecem interfaces semelhantes, normalmente escritos como uma biblioteca com base na API C.

A interface de socket Berkeley é definido em vários arquivos de cabeçalho. Os nomes e conteúdo desses arquivos diferem ligeiramente entre implementações. De um modo geral, eles incluem:

<sys/socket.h>
Funções e estruturas de dados principais do núcleo BSD.
<netinet/in.h>
Família de endereços AF e AF INET inet6 e seus protocolos correspondentes PF_INET e PF_INET6. Amplamente utilizado na Internet, que incluem endereços IP e números de porta TCP e UDP.
<sys/un.h>
Família de endereços PF_UNIX/PF_LOCAL. Usado para comunicação local entre os programas em execução no mesmo computador. Não é usado em redes.
<arpa/inet.h>
Funções para manipulação de endereços IP numéricos.
<netdb.h>
Funções para traduzir nomes de protocolos e nomes de host em endereços numéricos. Pesquisas de dados locais, bem como DNS.

As funções mais comumente usadas em sockets e que são providas pela API Berkeley sockets: socket(), bind(), listen(), connect(), accept(), send(), recv().

Qualquer sistema operacional moderno tem suporte a estas funções, como o Linux, o MAC OS e o Windows.

Exemplos de sockets cliente e servidor

Cliente

Servidor

Referências

http://en.wikipedia.org/wiki/Berkeley_sockets

http://www.binarytides.com/server-client-example-c-sockets-linux/

Translate »