Lors de l'implémentation de sockets Unix dans Go, il est essentiel d'établir un canal de communication bidirectionnel pour permettre au client et au serveur d'envoyer et de recevoir des données . Cet article explore un problème fondamental rencontré lors de l'utilisation de sockets Unix : les connexions unidirectionnelles conduisant à une transmission de données dans une seule direction.
Dans l'exemple de code fourni, le serveur peut recevoir des données de le client mais ne parvient pas à répondre avec des données. Ce problème vient du fait que l'appel c.Read() dans le code client n'est jamais suivi d'un appel c.Write(). En conséquence, le client ne parvient pas à lire la réponse du serveur, créant l'illusion d'une connexion unidirectionnelle.
Pour établir une communication bidirectionnelle, nous devons modifier à la fois le client et le serveur. code.
Le code du serveur modifié introduit une instruction defer pour gérer la fermeture gracieuse de la connexion en cas de problème. erreur. De plus, nous utilisons break pour quitter la goroutine du lecteur lorsque cela est nécessaire.
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) } }
Le code client modifié ajoute une goroutine de lecteur pour lire en continu les données entrantes du serveur. L'instruction defer garantit que la connexion est fermée à la fin de la fonction principale.
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) } }
Avec ces modifications, la communication client-serveur devient bidirectionnelle, permettant aux deux parties d'envoyer et de recevoir des données de manière transparente.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!