You need to enable JavaScript to run this app. 使用Golang创建多端口UDP服务器的代码问题解决求助
优惠活动
大模型
产品
解决方案
定价
更多

使用Golang创建多端口UDP服务器的代码问题解决求助

多UDP服务启动问题修正

你的代码存在4个核心问题,按如下方式调整即可正常启动多个UDP服务:

问题列表

  • 循环变量捕获错误:Go的for range循环中迭代变量r会被复用,所有启动的goroutine都捕获同一个r的地址,运行时实际拿到的是最后一次迭代的r值,导致所有服务都尝试监听最后一个端口,甚至触发空指针异常。
  • wg.Wait()位置错误:你将wg.Wait()放在了for循环内部,第一次迭代启动goroutine后就会阻塞等待,永远不会执行后续循环,最多只能启动1个UDP服务。
  • 缺少wg.Done()调用:goroutine执行完成后没有调用wg.Done(),会导致wg.Wait()永远阻塞。
  • 错误处理不合理:log.Fatalf会直接终止整个进程,单个端口监听失败会导致所有已启动的UDP服务一同退出,同时ReadFromUDP的返回值与错误未做处理,无法处理业务逻辑也不能感知连接异常。

修正后代码

for _, r := range routingTable.Routes {
    if r.Metric == 0 {
        wg.Add(1)
        // 将当前迭代的r作为值参数传入goroutine,解决循环变量捕获问题
        go func(curRoute Route) {
            defer wg.Done() // goroutine退出时通知WaitGroup
            conn, err := net.ListenUDP("udp4", &curRoute.OriginPort)
            if err != nil {
                log.Printf("启动端口%s的UDP服务失败: %s", curRoute.OriginPort.String(), err)
                return
            }
            defer conn.Close()
            log.Printf("正在监听端口: %s", curRoute.OriginPort.String())

            buffer := make([]byte, 1024)
            for {
                n, remoteAddr, err := conn.ReadFromUDP(buffer)
                if err != nil {
                    log.Printf("端口%s读取数据失败: %s", curRoute.OriginPort.String(), err)
                    break
                }
                // 此处补充你的业务逻辑,示例仅打印收到的报文
                log.Printf("端口%s收到来自%s的%d字节数据: %v", curRoute.OriginPort.String(), remoteAddr.String(), n, buffer[:n])
            }
        }(r) // 传入当前迭代的r值
    }
}
// 所有goroutine全部启动完成后再执行等待
wg.Wait()

注:如果你的Route结构体有自定义的类型名,替换代码中的Route为你实际的结构体类型名即可。


内容的提问来源于stack exchange,提问作者TheOneFromBrazil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 08:54:07