>> Tecnologia Eletrônica >  >> Telefones >> Viva-voz de Conferência

Como Cliente UDP Envia Datagramas: Fluxo bind(), sendto(), recvfrom()

Ciclo Vida Cliente UDP (POSIX Sockets)

Diferente TCP, UDP é connectionless. Cliente deve explicitamente bind porta local (opcional mas recomendado) e especificar destino a cada send.

Sequência Passo a Passo System Calls

1. Criar Socket

 int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) perror("socket"); 

2. Bind Porta Local (Opcional mas Recomendado)

 struct sockaddr_in local = {0}; local.sin_family = AF_INET; local.sin_addr.s_addr = htonl(INADDR_ANY); local.sin_port = htons(0); // 0 = OS atribui porta efêmera bind(sockfd, (struct sockaddr*)&local, sizeof(local)); 

Binding permite servidor responder porta conhecida e habilita regras firewall.

3. Resolver Endereço Servidor

 struct addrinfo hints = {0}, *res; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; getaddrinfo("server.example.com", "5000", &hints, &res); // res->ai_addr agora hold destination sockaddr_in 

4. Enviar Datagrama

 char *msg = "Hello UDP"; sendto(sockfd, msg, strlen(msg), 0, res->ai_addr, res->ai_addrlen); 

sendto argumentos: socket, buffer, length, flags (0), destination sockaddr, sockaddr length.

5. Receber Resposta (Opcional)

 char buf[1500]; struct sockaddr_in from; socklen_t fromlen = sizeof(from); ssize_t n = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen); if (n > 0) process(buf, n, &from); 

recvfrom bloqueia até datagrama chegar. from contém IP/porta sender.

6. Cleanup

 freeaddrinfo(res); close(sockfd); 

Diferenças-Chave vs TCP

AspectoTCPUDP
Conexãoconnect() estabeleceSem conexão; sendto especifica dest cada vez
ConfiabilidadeGarantida, ordenadaBest-effort; pode perder, reordenar, duplicar
Controle FluxoSim (window)Não (app deve pace)
Uso TípicoWeb, email, SSHDNS, NTP, VoIP, gaming, streaming, IoT

Armadilhas Comuns

  • Esquecer bind() → servidor responde porta efêmera; NAT/firewall pode dropar.
  • Não checar retorno sendto/recvfrom.
  • Assumir fronteiras datagrama preservadas (são, mas tamanho limitado ~64 KB, MTU prático ~1500).
  • recvfrom bloqueando forever — use select()/poll() ou setsockopt(SO_RCVTIMEO) para timeouts.