Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.9k views
in Technique[技术] by (71.8m points)

go - Unable to read from UNIX socket using net.Conn.Read

I'm trying to do simple UNIX socket communication with a service using GO. For testing I've created a socket like so:

$ nc -vlU /tmp/sock
Bound on /tmp/sock
Listening on /tmp/sock

And in GO, I net.Dial and try to write something, then read. I see the written data in the nc console, so I know that is working. But the net.Conn.Read operation appears non-blocking and will return immediately with zero length. From everything I've read and the example I've seen, this operation should block.

buf := make([]byte, 0, 4096)
ctl, err := net.Dial("unix", "/tmp/sock")
for {
    ctl.Write([]byte("test write
"))
    n, err := ctl.Read(buf)
    fmt.Printf("Len:%v, Data:%v, err:%v", n, buf, err)
}

I see the connection come through and data written ...

Connection received on /tmp/sock
test write
test write
test write
test write
...

But the GO console loops without blocking, reporting a zero length and no error

Len:0, Data:[], err:<nil>
Len:0, Data:[], err:<nil>
Len:0, Data:[], err:<nil>
Len:0, Data:[], err:<nil>
...

And of course if I type anything into the nc console nothing interesting happens in the GO program output.

Any idea what I'm doing wrong?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

short answer

buf := make([]byte, 0, 4096)

this code make a buffer with len=0!!!

do it like

buf := make([]byte, 4096)

example

this is some example i used, and they all works.

In practice, socket read and write should happen in two goroutines

package main

import (
    "bufio"
    "fmt"
    "io"
    "net"
    "time"
)

func main() {
    buf := make([]byte, 0, 4096)
    fmt.Println(buf)
    main03()
}

func main01() {
    // nc -vlU /tmp/sock0120
    ctl, err := net.Dial("unix", "/tmp/sock0120")
    if err != nil {
        fmt.Println(err)
        return
    }
    reader := bufio.NewReader(ctl)
    for {
        time.Sleep(time.Second)
        ctl.Write([]byte("test write
"))
        msg, err := reader.ReadString('
')
        fmt.Printf("Len:%v, Data:%v, err:%v
", len(msg), msg, err)
    }
}

func main02() {
    // nc -vlU /tmp/sock0120
    buf := make([]byte, 4)
    ctl, err := net.Dial("unix", "/tmp/sock0120")
    if err != nil {
        fmt.Println(err)
        return
    }
    reader := bufio.NewReader(ctl)
    for {
        time.Sleep(time.Second)
        ctl.Write([]byte("test write
"))
        n, err := io.ReadFull(reader, buf)
        fmt.Printf("Len:%v, Data:%v, err:%v
", n, buf, err)
    }
}

func main03() {
    // nc -vlU /tmp/sock0120
    buf := make([]byte, 4)
    ctl, err := net.Dial("unix", "/tmp/sock0120")
    if err != nil {
        fmt.Println(err)
        return
    }
    for {
        time.Sleep(time.Second)
        ctl.Write([]byte("test write
"))
        n, err := ctl.Read(buf)
        fmt.Printf("Len:%v, Data:%v, err:%v
", n, buf, err)
    }
}


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...