使用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
相关产品推荐
相关产品推荐

