【问题标题】:Unix Sockets in GoGo 中的 Unix 套接字
【发布时间】:2017-05-26 09:23:13
【问题描述】:

我正在尝试制作一个使用 Unix 套接字的简单回显客户端和服务器。在此示例中,连接似乎是单向的。服务器可以从客户端接收数据,但不能将数据发回。如果我改用 tcp 连接,它会很好用。有谁知道怎么回事?

服务器

package main

import "net"
import "fmt"

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

func main() {
    l, err := net.Listen("unix", "/tmp/echo.sock")
    if err != nil {
        println("listen error", err.String())
        return
    }

    for {
        fd, err := l.Accept()
        if err != nil {
            println("accept error", err.String())
            return
        }

        go echoServer(fd)
    }
}

客户

package main

import "net"
import "time"

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

【问题讨论】:

    标签: sockets go


    【解决方案1】:

    在您的示例客户端中,您似乎没有从服务器读取结果。当我添加代码来执行此操作时,我会看到来自服务器的结果。

    另外,看看我是如何使用 defer 和 break 来让 reader goroutine 退出的。

    服务器

    package main
    
    import (
        "log"
        "net"
    )
    
    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)
            }
        }
    }
    
    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)
        }
    }
    

    客户

    package main
    
    import (
        "io"
        "log"
        "net"
        "time"
    )
    
    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)
        }
    }
    

    【讨论】:

    • 这不再与最新版本的 Go 一起编译。错误上的String() 函数已被Error() 替换,netDial() 不再具有第二个参数。以下是我提出的修复建议但被拒绝:gist.github.com/nelsonjchen/510ab59caa85251c4709
    • 对不起,我找不到如何创建套接字。你能帮帮我吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    • 2015-05-07
    • 2021-07-19
    • 1970-01-01
    • 2019-02-12
    • 2017-06-10
    • 1970-01-01
    相关资源
    最近更新 更多