我可以net.Conn用encoding/goben/decoder包裝 TCP 的末端并通過它成功地 en/decode 一個值,但是如果我在原始連接上Decode使用 a Read,它會掛在Read:package mainimport ( "encoding/gob" "net" "log" "sync")func main() { var wg sync.WaitGroup addr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 9000} ready := make(chan struct{}) wg.Add(1) go func() { defer wg.Done() ln, err := net.ListenTCP("tcp4", addr) if err != nil { log.Fatal("ln: ", err) } defer ln.Close() close(ready) conn, err := ln.Accept() if err != nil { log.Fatal("conn: ", err) } defer conn.Close() var out string if err := gob.NewDecoder(conn).Decode(&out); err != nil { log.Fatal("error decoding: ", err) } if "hello" != out { log.Fatalf("1 expected '%s', got '%s'", "hello", out) } b := make([]byte, 1) log.Println("ready to read 1") if _, err := conn.Read(b); err != nil { log.Fatal("error reading: ", err) } log.Println("read 1") if b[0] != 1 { log.Fatalf("2 expected '%d', got '%d'", 1, b[0]) } if _, err := conn.Write([]byte{1}); err != nil { log.Fatal("err writing2: ", err) } log.Println("done 1") }() wg.Add(1) go func() { defer wg.Done() <-ready conn, err := net.DialTCP("tcp4", nil, addr) if err != nil { log.Fatal("conn2: ", err) }}輸出:2009/11/10 23:00:00 waiting2009/11/10 23:00:00 ready to read 22009/11/10 23:00:00 ready to read 1這會在 Go Playground 中導致死鎖恐慌并掛在我的本地機器上 ( go version go1.6.2 darwin/amd64),盡管代碼會間歇性地在本地執行到完成。如果我使用 anet.PipeConn或者如果我Decode使用 aWrite來代替(即在 en/decode 之后交換Read/的順序),則不會發生這種情況Write。當我刪除 en/decode 代碼時,en/decode 之后的代碼也可以單獨工作。是什么導致了這個掛起?這感覺像是一個緩存問題,但我不知道為什么Write不會刷新或為什么Read不會提取最新的可用數據,或者為什么這個問題只在gob涉及編碼/解碼時出現。
TCP `net.Conn.Read` 在使用`encoding/gob` 解碼器后掛起
慕尼黑8549860
2022-01-10 17:26:26