udp是无连接协议,go中dialudp仅绑定本地地址并记录远端地址,本质仍为sendto/recvfrom;服务端必须用listenudp,客户端固定单目标可用dialudp,多目标应选listenudp+writetoudp。

UDP 是无连接协议,Golang 里没有“建立 UDP 连接”这回事 —— net.DialUDP 返回的 *UDPConn 实际上只是绑定了本地地址并记录了远端地址,底层仍不握手、不保序、不重传。
为什么 DialUDP 看起来像“连接”
它封装了两步操作:创建 socket(net.ListenUDP) + 记录目标地址(用于后续 WriteTo 的简化调用)。本质仍是 sendto / recvfrom,不是 connect() 系统调用意义上的连接。
-
DialUDP后调用Write等价于WriteTo到预设远端地址,省去每次传addr - 但若远端不可达,错误只在第一次
Write或Read时暴露(比如 ICMP port unreachable) - 同一
*UDPConn无法切换目标地址;要发给不同服务端,得用WriteToUDP
ListenUDP 和 DialUDP 的适用场景区别
服务端必须用 ListenUDP,因为它需要接收任意来源的包;客户端可选 DialUDP(固定单目标)或直接 ListenUDP(需处理多源、或主动 WriteTo)。
本文档主要讲述的是android rtsp流媒体播放介绍;实时流协议(RTSP)是应用级协议,控制实时数据的发送。RTSP提供了一个可扩展框架,使实时数据,如音频与视频,的受控、点播成为可能。数据源包括现场数据与存储在剪辑中数据。该协议目的在于控制多个数据发送连接,为选择发送通道,如UDP、组播UDP与TCP,提供途径,并为选择基于RTP上发送机制提供方法。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
- 典型服务端:
ln, _ := net.ListenUDP("udp", &net.UDPAddr{Port: 8080}),然后ln.ReadFromUDP(buf) - 简单客户端:
conn, _ := net.DialUDP("udp", nil, &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8080}),之后conn.Write([]byte("hi")) - 若客户端要同时发给多个 IP,别用
DialUDP—— 直接ListenUDP+WriteToUDP更灵活
常见错误:UDP 包丢弃和超时控制
UDP 本身无超时机制。应用层必须自己处理:设置读写 deadline、用 context.WithTimeout 包裹 I/O 操作、或起 goroutine 配合 time.AfterFunc。
立即学习“go语言免费学习笔记(深入)”;
-
conn.SetReadDeadline(time.Now().Add(3 * time.Second))后Read超时会返回io.ErrDeadlineExceeded - 不要依赖
Write返回值判断对方是否收到 —— 它只表示内核发送缓冲区是否接纳了数据 - 防火墙、NAT、中间设备都可能导致包静默丢弃,无任何通知
- 局域网测试建议先用
nc -u或telnet(不推荐,改用echo "test" | nc -u host port)验证连通性
一个最小可行客户端示例(含错误处理)
addr, _ := net.ResolveUDPAddr("udp", "127.0.0.1:8080")
conn, err := net.DialUDP("udp", nil, addr)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
<p>conn.SetWriteDeadline(time.Now().Add(2 * time.Second))
_, err = conn.Write([]byte("ping"))
if err != nil {
log.Printf("write failed: %v", err) // 可能是 timeout 或 connection refused
return
}</p><p>conn.SetReadDeadline(time.Now().Add(2 * time.Second))
buf := make([]byte, 1024)
n, _, err := conn.ReadFromUDP(buf)
if err != nil {
log.Printf("read failed: %v", err) // 可能是 timeout 或 ICMP error
return
}
log.Printf("got reply: %s", buf[:n])
真正难的不是写通第一行 UDP 代码,而是设计好重试逻辑、序列号、校验、拥塞反馈 —— 这些得自己补,标准库不会帮你做。









