Maison > développement back-end > Golang > Comment réaliser une communication bidirectionnelle avec les sockets Unix en Go ?

Comment réaliser une communication bidirectionnelle avec les sockets Unix en Go ?

Mary-Kate Olsen
Libérer: 2024-12-02 01:25:11
original
986 Les gens l'ont consulté

How to Achieve Bidirectional Communication with Unix Sockets in Go?

Sockets Unix bidirectionnels dans Go

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.

Comprendre le problème

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.

Résoudre le problème

Pour établir une communication bidirectionnelle, nous devons modifier à la fois le client et le serveur. code.

Modification du serveur

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)
    }
}
Copier après la connexion

Modification du client

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)
    }
}
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal