BSD Sockets em linguagem C

Venho neste artigo explicar como funciona sockets em ANSi C, explicar portabilidade e exemplos reais e diferentes de artigos semelhantes. Enfim, aqui você aprenderá a usar sockets na prática.

[ Hits: 119.521 ]

Por: C00L3R_ em 06/07/2010 | Blog: https://github.com/CoolerVoid


Explanação ao TCP/IP



Antes de partir para o rock, vamos a uma leve introdução ao TCP/IP (Transmission Control Protocol/Internet Protocol). É um padrão de comunicação que reúne um conjunto de protocolos.

Tem livros como do Tanenbaum sobre redes que fala sobre isso, mas mesmo assim vou dar uma explicação, mesmo sendo bem incompleta...

Voltando ao termo TCP, o processo de aplicação transmite seus dados, de tamanho variável, fazendo chamadas ao TCP. Ao TCP cabe a fragmentação destes dados, formando os segmentos, que são unidades de transferência de dados do protocolo TCP. A troca de segmentos serve para estabelecer conexão, transferir dados etc.

Vamos entender alguns campos de segmento TCP:
  • Offset: (4 bits) tamanho do header TCP
  • Reserved: (6 bits) reservado para uso futuro
  • Flags: (6 bits)
  • URG: sinaliza um serviço urgente
  • ACK: envio de uma confirmação válida no cabeçalho
  • PSH: entrega de dados urgente à aplicação, sem bufferização
  • RST: resetar a conexão
  • SYN: sincronizar o nó de sequência
  • FIN: encerramento da conexão

Características principais:
  • Transferência em fluxo (stream) de dados
  • Confiabilidade (reconhecimento ACK)
  • Controle de fluxo (janela deslizante)
  • Multiplexação/demultiplexação
  • Conexões logicas (manutenção de status)
  • Full-duplex

Formato do segmento TCP:

0                                                          32
 ____________________________________________________________
|     Porta de Origem          |     Porta de destino        |
|------------------------------------------------------------| 
|                      Numero sequencial                     |
|------------------------------------------------------------|
|                 Numero de Reconhecimento                   |
|------------------------------------------------------------|
|Deslocamento | Reservado |URG|ACK|PSH|RST|SYN|FIN|  Janela  |
|------------------------------------------------------------|
|Checksum             |     Ponteiro de urgência             |
|------------------------------------------------------------|
|    Opções           |          Preenchimento               |
|------------------------------------------------------------|
|                           Dados                            |
|____________________________________________________________|

ou

  0           4              8           16     19    24                 32
   -------------------------------------------------------------------------
   |              Source Port             |         Destination Port       |
   -------------------------------------------------------------------------
   |                               Sequence Number                         |
   -------------------------------------------------------------------------
   |                             Acknowledgment Number                     |
   -------------------------------------------------------------------------
   | HLEN  |  Reserved |   Code Bits     |         Window                  |
   -------------------------------------------------------------------------
   |              Checksum               |         Urgent Pointer          |
   -------------------------------------------------------------------------
   |                                   Options    |        Padding         |
   -------------------------------------------------------------------------
   |                                    Data                               |
   -------------------------------------------------------------------------

Pessoal que já brincou com Nmap e firewalls sabe muito bem o que são estas flags. Detalhes do TCP, vide: http://www.faqs.org/rfcs/rfc793.html

Agora que já temos uma leve base de TCP, vamos para UDP.

UDP seria User Datagram Protocol, ou seja, permite que a aplicação escreva um datagrama encapsulado num pacote IPv4 ou IPv6, e então é enviado ao destino. Mas não há qualquer tipo de garantia que o pacote irá chegar ou não. Nem chega a ser confiável, mas é bom saber sua função, também dizemos que o UDP é um serviço sem conexão, pois não há necessidade de manter um relacionamento longo entre cliente e o servidor.

Assim, um cliente UDP pode criar um socket, enviar um datagrama para um servidor e imediatamente enviar outro datagrama com o mesmo socket para um servidor diferente. Da mesma forma, um servidor poderia ler datagramas vindos de diversos clientes, usando um único socket. A diferença básica entre o UDP e o TCP é o fato de que o TCP é um protocolo orientado à conexão e, portanto, inclui vários mecanismos para iniciar, manter e encerrar a comunicação, negociar tamanhos de pacotes, detectar e corrigir erros, evitar congestionamento do fluxo e permitir a retransmissão de pacotes corrompidos, independente da qualidade do meio físico.

ip == datagrama :)

Agora faltou explicar o que é IP, deveria ter explicado primeiro... IP é um acrônimo para a expressão inglesa "Internet Protocol" (ou Protocolo de Internet), que é um protocolo usado entre duas ou mais máquinas em rede para encaminhamento dos dados. Os dados numa rede IP são enviados em blocos referidos como pacotes ou datagramas (os termos são basicamente sinônimos no IP, sendo usados para os dados em diferentes locais nas camadas IP).

Em particular, no IP nenhuma definição é necessária antes do host tentar enviar pacotes para um host com o qual não comunicou previamente. O IP oferece um serviço de datagramas não confiável (também chamado de melhor esforço); ou seja, o pacote vem quase sem garantias. O pacote pode chegar desordenado (comparado com outros pacotes enviados entre os mesmos hosts), também podem chegar duplicados, ou podem ser perdidos por inteiro. Se a aplicação precisa de confiabilidade, esta é adicionada na camada de transporte.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Explanação ao TCP/IP
   3. O que é socket
   4. Funções read(), send() e exemplo cliente HTTP
   5. Funções listen(), bind(), accept() e exemplo de servidor HTTP
   6. Na prática fazendo um FUZZER TCP
   7. Servidor e cliente com fork
   8. Servidor de comandos e scanner de portas
   9. Simple socket library
   10. Explanação ao UDP e exemplo de servidor e cliente
   11. Exemplo UDP Flood
   12. Portabilidade
   13. Conclusão
Outros artigos deste autor

Usando o PF - Packet Filter

Ponteiros - Saindo de Pesadelos

Banco de dados orientados a documentos

Usando OpenBSD como desktop

Usando o NetBSD como desktop

Leitura recomendada

Monitorando o consumo de banda com Bwbar

O Modelo de Referência OSI

Controlando UPLOAD com o CBQ

Tutorial - Aplicação em C para transferência de arquivo usando socket TCP e Thread

Bibliotecas estáticas c/c++

  
Comentários
[1] Comentário enviado por VonNaturAustreVe em 06/07/2010 - 03:24h

Excelente cara vou ler tudo :)

[2] Comentário enviado por removido em 06/07/2010 - 05:29h

Hey C00L3R,
Parabéns, é um ótimo artigo. Minhas dúvidas surgiram após meus testes.
Um abraço.

[3] Comentário enviado por andrezc em 06/07/2010 - 08:12h

Cara, realmente esse é um dos melhores artigos que eu já li por aqui. Parabéns.

[4] Comentário enviado por werneral em 06/07/2010 - 11:18h

Muito bom! Obrigado!

[5] Comentário enviado por uberalles em 06/07/2010 - 11:43h

verdadeira aula, velho. parabéns!
muito bom "resumão" do Unix Network programming. Nunca consegui fazer nada decente em sockets e esta tua aula deverá me ajudar muito.

[6] Comentário enviado por stremer em 07/07/2010 - 15:28h

para quem interessar, ha algum tempo atras escrevi um script mostrando como criar um robo http e enviei ao VOL.

http://www.vivaolinux.com.br/script/Robo-HTTP-usando-socket-e-codigo-multiplataforma

Interessante para quem esta aprendendo sockets...

OTIMO ARTIGO

[7] Comentário enviado por andrezc em 07/07/2010 - 15:43h

Opa stremer, eu cheguei a ver este seu script, realmente fabuloso.

Um abraço.

[8] Comentário enviado por fernandopinheiro em 07/07/2010 - 20:23h

Parabens, muito bom!!

[9] Comentário enviado por brunosolar em 08/07/2010 - 09:48h

Parabens realmente muito bom. So queria fazer um comentario sobra a parte do UDP flood. Sim hoje em dia qualquer firewal simples pode recusar este tipo de pacote.

No entanto dependendo da quantidade de pacotes UDP enviados (leia-se DDOS) você poderá ser "derrubado" pois o firewall irá gastar muito processador para descatar todos os pacotes. A melhor solução (AINDA) para ataques DOS / DDOS é diretamente no ISP onde eles irão setar no roteador o IP do atacante para /dev/null (exemplo). claro que voce corre o risco de perder algum cliente que faça parte da rede redirecionada.

No mais excelente trabalho.

[10] Comentário enviado por shazaum em 24/09/2010 - 11:44h

opa, no fuzzer faltou uma lib...

#include <netinet/in.h>

[11] Comentário enviado por thomasawrd em 18/07/2014 - 12:41h

parabéns cara excelente artigo,me ajudou muito.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts