在Go 中實作Unix 套接字時,必須建立雙向通訊通道,讓客戶端和伺服器能夠發送和接收資料。本文探討了使用 Unix 套接字時遇到的一個基本問題:單向連接導致資料僅在一個方向傳輸。
在提供的程式碼範例中,伺服器可以從以下位置接收資料客戶端但未能回應資料。此問題源自於這樣一個事實:客戶端程式碼中的 c.Read() 呼叫之後永遠不會進行 c.Write() 呼叫。結果,客戶端無法讀取伺服器的回應,造成單向連線的假象。
要建立雙向通信,我們需要修改客戶端和伺服器程式碼。
修改後的伺服器程式碼引入了一個 defer 語句,以在出現以下情況時優雅地關閉連線 錯誤。此外,我們在必要時利用break來退出reader goroutine。
package main import ( "log" "net" ) func echoServer(c net.Conn) { defer c.Close() for { buf := make([]byte, 512) nr, err := c.Read(buf) if err != nil { return } data := buf[0:nr] println("Server got:", string(data)) _, err = c.Write(data) if err != nil { log.Fatal("Write: ", err) } } } func main() { l, err := net.Listen("unix", "/tmp/echo.sock") if err != nil { log.Fatal("listen error:", err) } for { fd, err := l.Accept() if err != nil { log.Fatal("accept error:", err) } go echoServer(fd) } }
修改後的客戶端程式碼增加了一個reader goroutine來連續讀取來自伺服器的傳入資料。 defer 語句確保連線在主函數終止時關閉。
package main import ( "io" "log" "net" "time" ) func reader(r io.Reader) { defer r.(net.Conn).Close() // Ensure connection is closed even on panic buf := make([]byte, 1024) for { n, err := r.Read(buf[:]) if err != nil { return } println("Client got:", string(buf[0:n])) } } func main() { c, err := net.Dial("unix", "/tmp/echo.sock") if err != nil { log.Fatal(err) } go reader(c) for { _, err := c.Write([]byte("hi")) if err != nil { log.Fatal(err) break } time.Sleep(1e9) } }
透過這些修改,客戶端-伺服器通訊變為雙向,允許雙方無縫發送和接收資料。
以上是Go中如何實現與Unix Sockets的雙向通訊?的詳細內容。更多資訊請關注PHP中文網其他相關文章!