dyhkwong:将底层 UDP 读取期限设为当前时间会使 quic-go 反复进入读取循环
在 Exclave #502 的高 CPU 占用反馈中,dyhkwong 给出一段与 Exclave 逻辑相似的 Go 示例:建立 QUIC 连接后,对底层 UDP socket 调用 SetReadDeadline(time.Now())。他说明,这会使所链接的 quic-go transport.go 读取循环不断重试,因为 net.Error.Temporary() 判断会持续成立。原帖附有完整示例和固定提交的源码行链接。
作者原文@dyhkwongExclave has a similar logic like the following:
package main import ( "context" "crypto/tls" "fmt" "net" "time" "github.com/quic-go/quic-go" ) func main() { packetConn, err := net.ListenUDP("udp", nil) if err != nil { fmt.Println(err) return } _, err = quic.Dial(context.Background(), packetConn, &net.UDPAddr{ IP: net.IPv4(223, 5, 5, 5), Port: 443, }, &tls.Config{ ServerName: "223.5.5.5", NextProtos: []string{"h3"}, }, nil) if err != nil { fmt.Println(err) return } packetConn.SetReadDeadline(time.Now()) time.Sleep(time.Second * 300) }Setting read deadline on the underlying UDP socket causes quic-go always repeating the read loop in https://github.com/quic-go/quic-go/blob/d961427ce89f4c1b574d8ec9884516440360e0ed/transport.go#L529-L556 (
nerr, ok := err.(net.Error); ok && nerr.Temporary()will always be successful).