Go UDP服务器必须用ReadFromUDP获取客户端真实地址并配对WriteToUDP发送响应,监听地址需用":端口"而非"localhost:端口"以接收外网包,缓冲区建议1400字节,避免conn.Write等错误调用。
UDP 在 Go 里不是“连上再发”,而是“收得到才发得对”——
返回的
是唯一可信的客户端地址,硬编码、复用监听地址或调用
都会发错甚至编译失败。
ListenUDP 绑定地址写错,外部机器根本连不上
Go 的
不像 TCP 那样默认监听所有接口。写成
或
只绑定回环地址,局域网其他设备的 UDP 包压根进不来。
正确做法是用
(等价于
),监听所有 IPv4 接口
若需限定网卡,显式写具体 IP,如
调试时可用
验证本地通,再用另一台机器
测外网
防火墙常被忽略:Linux 上检查
,macOS 留意“防火墙”设置是否拦截了 UDP
ReadFromUDP 和 WriteToUDP 必须配对使用
没有连接状态,
永远是
;每次收到包,
才返回真实的发送方地址,这个
必须原样传给下一次
。
错误写法:
→ 编译报错:
错误写法:
→ 地址写死,响应发给错误客户端
正确模式:先
,再
空包要过滤:
,否则
可能 panic 或解出零值
并发读写 UDPConn 的安全边界
是线程安全的,多个 goroutine 可并发调用;但
是阻塞 I/O,不能在单个 goroutine 里串行处理——否则整个服务卡死。
go语言参考手册 中文CHM版
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译
下载
立即学习
“
go语言免费学习笔记(深入)
”;
推荐结构:一个 goroutine 循环
,把
和
发到
Worker pool 处理业务逻辑(如解析、查表、生成响应),再统一用
回复
避免在 worker 中直接 close
或重复
,容易导致
缓冲区大小建议设为 1400–1500 字节(避开 IP 分片),别用
—— 内核接收队列溢出比 Go 层截断更难排查
为什么本地能通、线上一跑就丢包?
丢包往往不在 Go 代码里,而在系统层和节奏错配:Linux 默认 UDP 接收缓冲区小(常为 212992 字节),如果 Go 程序读得太慢,内核直接丢弃新包,且不通知用户态。
检查当前值:
,临时调大:
Go 层主动调大:
(需在
后立即设)
不要让
被长耗时逻辑阻塞:比如在 handler 里同步调用 HTTP API 或数据库查询,应异步化或加超时
监控指标:定期记录
中的
和
UDP 的“无连接”不是省事,是把连接管理、重传、去重、顺序保障全甩给业务层。Go 标准库只保证你能拿到原始数据报和源地址——剩下的,得自己画线、标号、计时、丢弃、重试。
ReadFromUDP*UDPAddrconn.Writenet.ListenUDP"localhost:8080""127.0.0.1:8080"":8080""0.0.0.0:8080""192.168.1.100:8080"nc -u 127.0.0.1 8080echo "test" | nc -u $SERVER_IP 8080sudo ufw statusUDPConnconn.RemoteAddr()nilReadFromUDP*UDPAddrWriteToUDPconn.Write([]byte("ack"))UDPConn.Write undefinedconn.WriteToUDP([]byte("ack"), &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 12345})n, addr, err := conn.ReadFromUDP(buf)conn.WriteToUDP([]byte("ack"), addr)if n == 0 { continue }json.Unmarshal(buf[:0], &v)WriteToUDPReadFromUDPReadFromUDPbuf[:n]addrchan struct{ data []byte; from *UDPAddr }conn.WriteToUDPconndefer conn.Close()use of closed network connection65507sysctl net.core.rmem_maxsudo sysctl -w net.core.rmem_max=4194304conn.SetReadBuffer(4 * 1024 * 1024)ListenUDPReadFromUDPnetstat -s | grep -A 5 "Udp:"packet receive errorsreceive buffer errors