Go - UDP 服务器读取缓冲区不会改变任何内容

问题描述 投票:0回答:1

我有一个简单的 UDP 服务器,它侦听数据包,等待 50 毫秒,就像正在执行操作一样,然后将消息打印到终端。这是服务器代码:

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
    }
}

我有一个 go 客户端代码,它只是向该服务器发送一次字符串消息。这是客户端代码:

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)
    }
}

我想测试服务器可以处理多少数据包。所以我所做的是,我按顺序运行客户端代码 10000 次,看看将处理其中的多少个。但每次只处理大约 400-500 个数据包。这是我从终端进行测试的方法:

time (for i in $(seq 10000); do ./client; done)

没有错误日志,输出为:

real    0m12,538s
user    0m10,667s
sys     0m4,014s

我认为这可能是由于操作系统缓冲区限制而导致的问题。所以我在服务器代码中

go startWorker(id, conn)
之前添加了以下代码:

// 1 MB
if err = conn.SetReadBuffer(1024 * 1024 * 1024); err != nil {
    log.Fatal(err)
}

进行完全相同的测试后,处理的数据包数量变为 600-700。对于 10000 个这个简单的“Hello UDP Server”,1 MB 缓冲区不可能不够 “消息。任何人都可以向我解释这种行为背后的原因以及如何解决它吗?

P.S.:我使用的是 Ubuntu 22.04

go udp
1个回答
0
投票

尝试增加操作系统上 UDP 缓冲区的大小。您可以根据您的操作系统使用这些命令:

Linux:

sudo sysctl -w net.core.rmem_max=...

Mac操作系统:

sudo sysctl -w net.inet.udp.recvspace=...

Windows:
在Windows上,您可以通过修改注册表来调整UDP缓冲区大小。相关按键是

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Afd\Parameters\DefaultReceiveWindow

© www.soinside.com 2019 - 2024. All rights reserved.