Go语言UDP本地请求出现约5%丢包问题求助
本地UDP高丢包问题排查求助
服务端代码(server.go)
package main //server.go import ( "fmt" "net" "os" "os/signal" "syscall" ) func main() { tcp := 0 udp := 0 defer func(o, t *int) { fmt.Println(*o, *t) }(&tcp, &udp) go func() { l, err := net.ListenTCP("tcp", &net.TCPAddr{ IP: net.ParseIP("0.0.0.0"), Port: 3000, }) if err != nil { panic(err) } b := make([]byte, 24) for { conn, err := l.Accept() if err != nil { continue } n, err := conn.Read(b) if err != nil { continue } r := string(b[:n]) if r == "close" { conn.Close() break } else { _, err = conn.Write([]byte("pong")) if err != nil { continue } } conn.Close() tcp++ } l.Close() }() go func() { conn, err := net.ListenUDP("udp", &net.UDPAddr{ IP: net.ParseIP("0.0.0.0"), Port: 3000, }) if err != nil { panic(err) } b := make([]byte, 24) for { n, addr, err := conn.ReadFromUDP(b) if err != nil { continue } r := string(b[:n]) if r == "close" { break } else { _, err = conn.WriteToUDP([]byte("pong"), addr) if err != nil { continue } } udp++ } conn.Close() }() signals := make(chan os.Signal, 1) signal.Notify(signals, os.Interrupt, syscall.SIGTERM) <-signals }
客户端代码(client.go)
package main //client.go import ( "fmt" "net" "os" "os/signal" "strconv" "sync/atomic" "syscall" "time" ) func main() { t := "tcp" m := "ping" c := 1 if len(os.Args) > 1 { t = os.Args[1] } if len(os.Args) > 2 { m = os.Args[2] } if len(os.Args) > 3 { c, _ = strconv.Atoi(os.Args[3]) } tcp := int64(0) udp := int64(0) defer func(o, t *int64) { fmt.Println(*o, *t) }(&tcp, &udp) if c == 1 { if t == "tcp" { addr, err := net.ResolveTCPAddr("tcp", ":3000") if err != nil { panic(err) } conn, err := net.DialTCP("tcp", nil, addr) if err != nil { panic(err) } _, err = conn.Write([]byte(m)) if err != nil { panic(err) } tcp++ } if t == "udp" { addr, err := net.ResolveUDPAddr("udp", ":3000") if err != nil { panic(err) } conn, err := net.DialUDP("udp", nil, addr) if err != nil { panic(err) } _, err = conn.Write([]byte(m)) if err != nil { panic(err) } udp++ } os.Exit(0) } for i := 0; i < c; i++ { go func() { a1, err := net.ResolveTCPAddr("tcp", ":3000") if err != nil { panic(err) } c1, err := net.DialTCP("tcp", nil, a1) if err != nil { panic(err) } _, err = c1.Write([]byte(m)) if err != nil { panic(err) } buf := make([]byte, 24) n, err := c1.Read(buf) if err != nil { panic(err) } if string(buf[:n]) != "pong" { panic(1) } err = c1.Close() if err != nil { panic(err) } g := atomic.AddInt64(&tcp, 1) if g % 100 == 0 { fmt.Println("tcp", g) time.Sleep(time.Millisecond * 1000) } }() go func() { a2, err := net.ResolveUDPAddr("udp", ":3000") if err != nil { panic(err) } c2, err := net.DialUDP("udp", nil, a2) if err != nil { panic(err) } _, err = c2.Write([]byte(m)) if err != nil { panic(err) } buf := make([]byte, 24) n, err := c2.Read(buf) if err != nil { panic(err) } if string(buf[:n]) != "pong" { panic(1) } err = c2.Close() if err != nil { panic(err) } g := atomic.AddInt64(&udp, 1) if g % 100 == 0 { fmt.Println("udp", g) time.Sleep(time.Millisecond * 1000) } }() } signals := make(chan os.Signal, 1) signal.Notify(signals, os.Interrupt, syscall.SIGTERM) <-signals }
问题现象
发送100或200个请求时,服务端与客户端均显示所有UDP请求正常处理;但发送1000个请求时,UDP请求出现约5%的丢包,且无panic抛出。虽然UDP本身允许丢包,但本地localhost环境下该丢包率过高,怀疑存在代码或逻辑问题,寻求排查帮助。
内容的提问来源于stack exchange,提问作者Gohryt
相关产品推荐
相关产品推荐

