Eu tenho um servidor UDP simples que escuta pacotes, espera 50 milissegundos para se comportar como se houvesse uma operação em andamento e depois imprime a mensagem no terminal. Aqui está o código do servidor:
package main
import (
"fmt"
"log"
"log/slog"
"net"
"time"
)
func main() {
udpAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:8080")
if err != nil {
log.Fatal(err)
}
conn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
log.Fatal(err)
}
slog.Info("UDP server listening", "addr", udpAddr, "workers", numCpu)
go startWorker(0, conn)
// Block forever
<-make(chan struct{})
}
func startWorker(id int, conn *net.UDPConn) {
slog.Info("Starting worker", "id", id)
i := 0
for {
buf := make([]byte, 1024)
_, _, err := conn.ReadFromUDP(buf)
if err != nil {
slog.Error("failed to read UDP message", "err", err, "worker", id)
continue
}
time.Sleep(50 * time.Millisecond)
fmt.Print(i, " > ", string(buf))
i += 1
}
}
Eu tenho um código de cliente go que simplesmente envia uma mensagem de string para este servidor uma vez. Aqui está o código do cliente:
package main
import (
"log"
"net"
)
func main() {
udpAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:8080")
if err != nil {
log.Fatal(err)
}
conn, err := net.DialUDP("udp", nil, udpAddr)
if err != nil {
log.Fatal(err)
}
// Send a message to the server
_, err = conn.Write([]byte("Hello UDP Server\n"))
if err != nil {
log.Fatal(err)
}
}
Eu queria testar quantos pacotes podem ser manipulados no servidor. Então, o que fiz foi executar o código do cliente 10.000 vezes sequencialmente para ver quantos deles serão tratados. Mas sempre, apenas cerca de 400-500 pacotes são processados. Aqui está como fiz o teste no terminal:
time (for i in $(seq 10000); do ./client; done)
Não houve logs de erros e a saída foi:
real 0m12,538s
user 0m10,667s
sys 0m4,014s
Presumi que isso poderia ser um problema devido às limitações do buffer do sistema operacional. Então adicionei o seguinte código antes go startWorker(id, conn)
no código do servidor:
// 1 GB
if err = conn.SetReadBuffer(1024 * 1024 * 1024); err != nil {
log.Fatal(err)
}
Depois de fazer exatamente o mesmo teste, o número de pacotes processados passou de 600 a 700. Não há como 1 GB de buffer não ser suficiente para 10.000 desta simples mensagem "Hello UDP Server\n". Alguém pode me explicar o motivo desse comportamento e como posso corrigi-lo?
PS : Estou usando Ubuntu 22.04
Tente aumentar o tamanho do buffer UDP no seu sistema operacional. Você pode usar estes comandos dependendo do seu sistema operacional:
Linux:
Mac OS:
Windows:
No Windows, você pode ajustar o tamanho do buffer UDP modificando o registro. A chave relevante é
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Afd\Parameters\DefaultReceiveWindow
.