Heim > Backend-Entwicklung > Golang > Wie erreicht man eine bidirektionale Kommunikation mit Unix-Sockets in Go?

Wie erreicht man eine bidirektionale Kommunikation mit Unix-Sockets in Go?

Mary-Kate Olsen
Freigeben: 2024-12-02 01:25:11
Original
978 Leute haben es durchsucht

How to Achieve Bidirectional Communication with Unix Sockets in Go?

Bidirektionale Unix-Sockets in Go

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.

Das Problem verstehen

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.

Lösung des Problems

Um eine bidirektionale Kommunikation herzustellen, müssen wir sowohl den Client als auch den Server ändern Code.

Serveränderung

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)
    }
}
Nach dem Login kopieren

Client-Modifikation

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)
    }
}
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage