问题描述
我正在尝试使用 GO 与服务进行简单的 UNIX 套接字通信。为了测试,我创建了一个像这样的套接字:
$ nc -vlU /tmp/sock
Bound on /tmp/sock
Listening on /tmp/sock
在 GO 中,我 net.Dial
并尝试写一些东西,然后阅读。我在 nc
控制台中看到写入的数据,所以我知道这是有效的。但是 net.Conn.Read
操作似乎是非阻塞的,并且会立即以零长度返回。从我读过的所有内容和我看到的示例来看,此操作应该会阻塞。
buf := make([]byte,4096)
ctl,err := net.Dial("unix","/tmp/sock")
for {
ctl.Write([]byte("test write\n"))
n,err := ctl.Read(buf)
fmt.Printf("Len:%v,Data:%v,err:%v",n,buf,err)
}
我看到连接成功并写入数据...
Connection received on /tmp/sock
test write
test write
test write
test write
...
但是GO控制台循环没有阻塞,报告零长度并且没有错误
Len:0,Data:[],err:<nil>
Len:0,err:<nil>
...
当然,如果我在 nc
控制台中输入任何内容,GO 程序输出中不会发生任何有趣的事情。
知道我做错了什么吗?
解决方法
简答
buf := make([]byte,4096)
这段代码用 len=0
制作一个缓冲区!!!
喜欢就好
buf := make([]byte,4096)
示例
这是我使用的一些示例,它们都有效。
实际上,socket读写应该发生在two goroutines
package main
import (
"bufio"
"fmt"
"io"
"net"
"time"
)
func main() {
buf := make([]byte,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\n"))
msg,err := reader.ReadString('\n')
fmt.Printf("Len:%v,Data:%v,err:%v\n",len(msg),msg,err)
}
}
func main02() {
// nc -vlU /tmp/sock0120
buf := make([]byte,4)
ctl,"/tmp/sock0120")
if err != nil {
fmt.Println(err)
return
}
reader := bufio.NewReader(ctl)
for {
time.Sleep(time.Second)
ctl.Write([]byte("test write\n"))
n,err := io.ReadFull(reader,buf)
fmt.Printf("Len:%v,n,buf,err)
}
}
func main03() {
// nc -vlU /tmp/sock0120
buf := make([]byte,"/tmp/sock0120")
if err != nil {
fmt.Println(err)
return
}
for {
time.Sleep(time.Second)
ctl.Write([]byte("test write\n"))
n,err := ctl.Read(buf)
fmt.Printf("Len:%v,err)
}
}