Как гарантировать доставку с UDP

«Как гарантировать доставку с UDP» — вопрос из категории Сети, который задают на 23% собеседований Golang Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

UDP не гарантирует доставку, но можно реализовать подтверждения (ACK) и повторные передачи. Пример:

// Клиент отправляет пакет с порядковым номером
func sendPacket(conn *net.UDPConn, seq int, data []byte) {
    packet := append([]byte{byte(seq)}, data...)
    conn.Write(packet)

    // Таймаут для ожидания ACK
    conn.SetReadDeadline(time.Now().Add(1 * time.Second))

    for {
        buf := make([]byte, 1)
        _, err := conn.Read(buf)
        if err == nil && buf[0] == byte(seq) {
            break // Получен ACK
        }
        conn.Write(packet) // Повторная отправка
    }
}

// Сервер подтверждает получение
func handlePacket(buf []byte, conn *net.UDPConn, addr *net.UDPAddr) {
    seq := buf[0]
    data := buf[1:]
    // Обработка данных...
    conn.WriteToUDP([]byte{seq}, addr) // Отправка ACK
}

Ключевые моменты:

  1. Последовательные номера пакетов
  2. Таймауты и повторные отправки
  3. Подтверждения получения (ACK)
  4. Контроль дубликатов на стороне получателя