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
Linda HamiltonOriginal
2024-12-08 06:28:15613browse

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())
        }
    }
}

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)
    }
}

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)
        }
    }
}

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)
    }
}

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!

Statement:
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