Home > Backend Development > Golang > Why is my Go Unix Socket Connection Unidirectional, and How Can I Fix It?

Why is my Go Unix Socket Connection Unidirectional, and How Can I Fix It?

Linda Hamilton
Release: 2024-12-08 06:28:15
Original
614 people have browsed it

Why is my Go Unix Socket Connection Unidirectional, and How Can I Fix It?

Unix Sockets in Go: A Unidirectional Connection Issue

One common challenge when working with Unix sockets in Go is that the connection may sometimes become unidirectional. While data can be received by one party, sending data back results in no response.

Let's analyze a code example provided in a forum thread to identify the cause:

Server Code:

func echoServer(c net.Conn) {
    for {
        buf := make([]byte, 512)
        nr, err := c.Read(buf)
        if err != nil {
            return
        }

        data := buf[0:nr]
        fmt.Printf("Received: %v", string(data))
        _, err = c.Write(data)
        if err != nil {
            panic("Write: " + err.String())
        }
    }
}
Copy after login

Client Code:

func main() {
    c,err := net.Dial("unix","", "/tmp/echo.sock")
    if err != nil {
        panic(err.String())
    }
    for {
        _,err := c.Write([]byte("hi\n"))
        if err != nil {
            println(err.String())
        }
        time.Sleep(1e9)
    }
}
Copy after login

Upon reviewing the code, we notice that the client is not reading the response sent by the server. This is causing a problem where the client keeps sending data to the server but never receives a response.

Solution:

To fix this issue, we need to add a goroutine in the client to handle reading the response from the server. After making this modification, the code will operate as intended:

Revised Server Code:

func echoServer(c net.Conn) {
    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)
        }
    }
}
Copy after login

Revised Client Code:

func reader(r io.Reader) {
    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 {
        panic(err)
    }
    defer c.Close()

    go reader(c)
    for {
        _, err := c.Write([]byte("hi"))
        if err != nil {
            log.Fatal("write error:", err)
            break
        }
        time.Sleep(1e9)
    }
}
Copy after login

With these changes, the server can receive data from the client and also send responses back, resulting in a bidirectional communication channel.

The above is the detailed content of Why is my Go Unix Socket Connection Unidirectional, and How Can I Fix It?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template