在 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中文网其他相关文章!