UDP是一种无连接的传输层协议,具有传输速度快、开销小的特点,适合对实时性要求高、能容忍少量丢包的场景。在Golang中,我们可以通过标准库的net包快速实现UDP Server的创建和监听功能。

UDP Server核心实现步骤
使用Golang创建UDP Server主要分为三个核心步骤:解析监听地址、创建UDP连接、循环处理收发数据。下面我们逐步拆解每个步骤的实现细节。
1. 解析监听地址
首先需要定义UDP Server要监听的地址和端口,使用net.ResolveUDPAddr函数可以将字符串形式的地址解析为*net.UDPAddr类型,这是后续创建连接的基础。
package main
import (
"fmt"
"net"
)
func main() {
// 定义监听的地址和端口,这里监听本地8080端口
udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8080")
if err != nil {
fmt.Println("解析地址失败:", err)
return
}
fmt.Println("地址解析成功:", udpAddr)
}
2. 创建UDP监听连接
地址解析完成后,使用net.ListenUDP函数创建UDP连接,该函数会返回一个*net.UDPConn类型的对象,后续所有的数据收发都通过这个对象完成。
package main
import (
"fmt"
"net"
)
func main() {
udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8080")
if err != nil {
fmt.Println("解析地址失败:", err)
return
}
// 创建UDP监听连接
conn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
fmt.Println("创建UDP连接失败:", err)
return
}
// 函数退出时关闭连接
defer conn.Close()
fmt.Println("UDP Server启动成功,监听地址:", conn.LocalAddr())
}
3. 循环处理数据收发
UDP Server启动后需要持续监听客户端发送的数据,使用ReadFromUDP方法可以读取客户端发来的数据,同时获取客户端的地址,之后可以通过WriteToUDP方法向对应客户端返回数据。
package main
import (
"fmt"
"net"
)
func main() {
udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8080")
if err != nil {
fmt.Println("解析地址失败:", err)
return
}
conn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
fmt.Println("创建UDP连接失败:", err)
return
}
defer conn.Close()
fmt.Println("UDP Server启动成功,等待客户端数据...")
// 定义接收数据的缓冲区,大小为1024字节
buf := make([]byte, 1024)
for {
// 读取客户端发来的数据,返回读取的字节数、客户端地址、错误信息
n, clientAddr, err := conn.ReadFromUDP(buf)
if err != nil {
fmt.Println("读取数据失败:", err)
continue
}
// 打印接收到的数据和客户端地址
fmt.Printf("收到来自 %v 的数据: %sn", clientAddr, string(buf[:n]))
// 向客户端返回响应数据
response := []byte("已收到你的消息")
_, err = conn.WriteToUDP(response, clientAddr)
if err != nil {
fmt.Println("发送响应失败:", err)
}
}
}
UDP Server开发注意事项
- 缓冲区大小设置:接收数据的缓冲区大小需要根据实际传输的数据大小合理设置,避免缓冲区过小导致数据截断。
- 连接关闭处理:一定要在程序退出前关闭
UDPConn连接,避免端口占用问题。 - 超时设置:如果需要设置读取超时,可以调用
conn.SetReadDeadline方法,超时后会返回对应的错误,方便做超时逻辑处理。 - 并发处理:如果单条数据处理逻辑复杂,可以开启协程处理每条接收到的数据,避免阻塞后续的接收流程。
完整UDP Server示例
下面是一个包含超时设置和简单并发处理的完整UDP Server示例,适合直接作为基础模板使用。
package main
import (
"fmt"
"net"
"time"
)
func handleClient(conn *net.UDPConn, data []byte, clientAddr *net.UDPAddr) {
// 模拟数据处理耗时
time.Sleep(100 * time.Millisecond)
response := []byte(fmt.Sprintf("已处理你的消息,长度: %d", len(data)))
_, err := conn.WriteToUDP(response, clientAddr)
if err != nil {
fmt.Println("响应客户端失败:", err)
}
}
func main() {
udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8080")
if err != nil {
fmt.Println("解析地址失败:", err)
return
}
conn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
fmt.Println("创建UDP连接失败:", err)
return
}
defer conn.Close()
fmt.Println("UDP Server启动成功,监听地址:", conn.LocalAddr())
buf := make([]byte, 1024)
for {
// 设置读取超时为5秒
conn.SetReadDeadline(time.Now().Add(5 * time.Second))
n, clientAddr, err := conn.ReadFromUDP(buf)
if err != nil {
// 判断是否为超时错误,超时后继续监听
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
fmt.Println("读取超时,继续监听...")
continue
}
fmt.Println("读取数据失败:", err)
continue
}
// 开启协程处理客户端数据,避免阻塞接收
go handleClient(conn, buf[:n], clientAddr)
}
}
GolangUDP_ServerUDP监听net包修改时间:2026-07-07 19:36:28