UDP 通讯的一个要点是收到的数据一定要先进行缓存,放到队列中等后续处理。如果在接收的同时进行处理会导致消息处理不过来,最后导致堵塞的问题

通过一个 Deque 的开源组件

edwingeng/deque: A highly optimized double-ended queue (github.com) 一个队列的实现,使用这个解决 UDP 发送数据快导致的接收处理不过来的问题

dq := deque.NewDeque[int]()
dq.PushBack(100)
dq.PushBack(200)
dq.PushBack(300)
for !dq.IsEmpty() {
    fmt.Println(dq.PopFront())
}
 
dq.PushFront(100)
dq.PushFront(200)
dq.PushFront(300)
for i, n := 0, dq.Len(); i < n; i++ {
    fmt.Println(dq.PopFront())
}
 
// Output:
// 100
// 200
// 300
// 300
// 200
// 100

通过 Go消息队列的方案

这是一个比较推荐的方案,使用消息队列是 Go 自带的功能,而且不用担心并发的问题

// 创建消息队列
queue := make(chan interface{}, 1024)
 
// 接收数据
go func() {
    // 监听UDP端口
    conn, err := net.ListenUDP("udp", &net.UDPAddr{
        IP:   net.ParseIP("0.0.0.0"),
        Port: 8080,
    })
    if err != nil {
        panic(err)
    }
 
    defer conn.Close()
 
    // 接收包
    for {
        buf := make([]byte, 1024)
        n, _, err := conn.ReadFromUDP(buf)
        if err != nil {
            panic(err)
        }
 
        // 将包放入消息队列
        queue <- buf[:n]
    }
}()
 
// 处理数据
go func() {
    for {
        // 从消息队列中取出数据
        buf := <-queue
 
        // 处理数据
        // ...
    }
}()