Pular para o conteúdo principal

victorstein.dev

54/100 Dias de Golang - Sockets em UDP

Table of Contents

# Sockets em UDP

No post passado fizemos uma aplicação usando o Melody, que serve para facilitar o uso de Websockets. O websocket é um protocolo que está sobre o HTTP e o HTTP roda sobre o TCP. Vamos ver aqui uma implementação de sockets usando UDP, não confunda o Socket com Websocket. Websocket é o protocolo e socket é uma interface de comunicação. E hoje faremos um socket UDP. O UDP (User Datagram Protocol) é ideal para aplicações que priorizam velocidade sobre confiabilidade. UDP é um protocolo sem conexão que não garante entrega de pacotes, não mantém orde de mensagens e possui baixo overhead em relação ao TCP. Em Go, trabalhar com UDP é simples pois podemos usar a lib padrão net. Veja a implementação de um server:

package main

import (
    "fmt"
    "net"
    "log"
)

func main() {
    // Criar endereço UDP na porta 8080
    addr, err := net.ResolveUDPAddr("udp", ":8080")
    if err != nil {
        log.Fatal(err)
    }
    
    // Iniciar servidor UDP
    conn, err := net.ListenUDP("udp", addr)
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()
    
    fmt.Println("Servidor UDP iniciado na porta 8080")
    
    buffer := make([]byte, 1024)
    
    for {
        n, clientAddr, err := conn.ReadFromUDP(buffer)
        if err != nil {
            log.Println("Erro ao ler:", err)
            continue
        }
        
        message := string(buffer[:n])
        fmt.Printf("Mensagem recebida de %s: %s\n", clientAddr, message)
        
        response := []byte("Mensagem recebida com sucesso!")
        _, err = conn.WriteToUDP(response, clientAddr)
        if err != nil {
            log.Println("Erro ao responder:", err)
        }
    }
}

O código do server é muito parecido com o do server em TCP, as principais mudanças são em relação as funções UDP. O código do client é bem similar também:

package main

import (
    "fmt"
    "net"
    "log"
)

func main() {
    // Resolver endereço do servidor
    serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8080")
    if err != nil {
        log.Fatal(err)
    }
    
    conn, err := net.DialUDP("udp", nil, serverAddr)
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()
    
    message := []byte("Olá, servidor UDP!")
    _, err = conn.Write(message)
    if err != nil {
        log.Fatal(err)
    }
    
    buffer := make([]byte, 1024)
    n, _, err := conn.ReadFromUDP(buffer)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Resposta do servidor: %s\n", string(buffer[:n]))
}

Nese exemplo mandamos um “Olá, servidor UDP!” e o servidor responde com “Mensagem recebida com sucesso!”