Bei der Implementierung von Unix-Sockets in Go ist es wichtig, einen bidirektionalen Kommunikationskanal einzurichten, damit sowohl der Client als auch der Server Daten senden und empfangen können . In diesem Artikel wird ein grundlegendes Problem untersucht, das bei der Verwendung von Unix-Sockets auftritt: unidirektionale Verbindungen, die zur Datenübertragung nur in eine Richtung führen.
Im bereitgestellten Codebeispiel kann der Server Daten von empfangen Der Client antwortet jedoch nicht mit Daten. Dieses Problem ergibt sich aus der Tatsache, dass auf den c.Read()-Aufruf im Clientcode niemals ein c.Write()-Aufruf folgt. Infolgedessen kann der Client die Antwort des Servers nicht lesen, wodurch die Illusion einer unidirektionalen Verbindung entsteht.
Um eine bidirektionale Kommunikation herzustellen, müssen wir sowohl den Client als auch den Server ändern Code.
Der geänderte Servercode führt eine Defer-Anweisung ein, um das ordnungsgemäße Schließen der Verbindung im Falle eines zu handhaben Fehler. Darüber hinaus verwenden wir break, um die Reader-Goroutine bei Bedarf zu beenden.
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) } }
Der geänderte Client-Code fügt eine Reader-Goroutine hinzu, um kontinuierlich eingehende Daten vom Server zu lesen. Die Defer-Anweisung stellt sicher, dass die Verbindung nach Beendigung der Hauptfunktion geschlossen wird.
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) } }
Mit diesen Änderungen wird die Client-Server-Kommunikation bidirektional, sodass beide Parteien nahtlos Daten senden und empfangen können.
Das obige ist der detaillierte Inhalt vonWie erreicht man eine bidirektionale Kommunikation mit Unix-Sockets in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!