我有一个连接主机名的地图,我试图将其传递给我在Go中编写的应用程序的不同模块。
var conns_ map[string]net.Conn // tcp connections per node
在主server.go文件中,我拨打网络中的其他服务器并保存与此地图的连接:
conn, err := net.Dial("tcp", address)
conns_[hostname] = conn
然后我想将此地图发送到其他模块以重新使用连接。以下是我如何将其发送到学习者模块的示例:
go learner.ListenForNotifies(conns_, selfname_)
在学习者模块中,我拿起地图并开始尝试在它包含的每个连接上使用gob.Decoder:
func ListenForNotifies(conns map[string]net.Conn, selfname string) {
for hostname, conn := range conns {
go listen(hostname, conn, lChan)
}
// etc.
}
在listen函数中:
func listen(hostname string, conn net.Conn, lChan chan string) {
decoder := gob.NewDecoder(conn)
proposal := &utils.Proposal{}
err := decoder.Decode(proposal)
// etc.
}
问题在于,当我在这里调用decoder.Decode(提案)时,会发生恐慌:
panic: runtime error: invalid memory address or nil pointer dereference
我在其他地方使用相同的编码/解码代码没有问题,唯一的区别是我正在尝试重新使用连接,而不是在同一个函数中建立新的连接后立即调用解码。我一直试图让这个工作好几个小时,试图通过引用传递东西,使用map [string] interface {},以及各种没有运气的东西。 Gob.decode应该阻塞,直到在底层的net.Conn对象上编码某些东西,对吗?我只能猜测net.Conn对象在某种程度上已经失效了。
我是否在传递连接对象时出错?我读到net.Conn是一个非常简单的对象,可以通过值传递,但我必须遗漏一些东西。当尝试使用类型interface {}通过引用传递它时,我得到了如下错误:
interface {} does not implement net.Conn (missing Close method)
我现在不知所措,试图找出连接对象可能出现的问题,如果我误用了gob.Decode,将net.Conn对象放入地图有问题,或者问题是完全不同的东西。
有什么想法吗?
编辑:完整的恐慌追溯如下:
goroutine 16 [running]:
runtime.panic(0x527040, 0x6afe68)
/usr/local/go/src/pkg/runtime/panic.c:266 +0xb6
bufio.(*Reader).fill(0xc21004a180)
/usr/local/go/src/pkg/bufio/bufio.go:91 +0x10a
bufio.(*Reader).Read(0xc21004a180, 0xc21000aa30, 0x1, 0x9, 0x1, ...)
/usr/local/go/src/pkg/bufio/bufio.go:159 +0x1a4
io.ReadAtLeast(0x7f2e22e8a360, 0xc21004a180, 0xc21000aa30, 0x1, 0x9, ...)
/usr/local/go/src/pkg/io/io.go:288 +0xf6
io.ReadFull(0x7f2e22e8a360, 0xc21004a180, 0xc21000aa30, 0x1, 0x9, ...)
/usr/local/go/src/pkg/io/io.go:306 +0x71
encoding/gob.decodeUintReader(0x7f2e22e8a360, 0xc21004a180, 0xc21000aa30, 0x9, 0x9, ...)
/usr/local/go/src/pkg/encoding/gob/decode.go:66 +0x98
encoding/gob.(*Decoder).recvMessage(0xc210069000, 0x0)
/usr/local/go/src/pkg/encoding/gob/decoder.go:73 +0x57
encoding/gob.(*Decoder).decodeTypeSequence(0xc210069000, 0xc210045f00, 0x160)
/usr/local/go/src/pkg/encoding/gob/decoder.go:159 +0x49
encoding/gob.(*Decoder).DecodeValue(0xc210069000, 0x4ea300, 0xc210045f60, 0x160, 0x0, ...)
/usr/local/go/src/pkg/encoding/gob/decoder.go:223 +0x12e
encoding/gob.(*Decoder).Decode(0xc210069000, 0x4ea300, 0xc210045f60, 0xb, 0x0)
/usr/local/go/src/pkg/encoding/gob/decoder.go:202 +0x1c5
group10/lab5/learner.listen(0x565f90, 0x12, 0x0, 0x0, 0xc21004a120)
/home/dev/go/src/learner/learner.go:51 +0x163
created by group10/lab5/learner.ListenForNotifies
/home/dev/go/src/learner/learner.go:26 +0x18a
更新:问题被发现了!我没有意识到你可以通过fmt.Println(conn)获取更多信息,并发现conn是零,这引起了恐慌。对不起,感谢您的帮助。
答案 0 :(得分:1)
更新:问题被发现了!我没有意识到你可以通过fmt.Println(conn)从中获取更多信息,并发现conn是零,这引起了恐慌。对不起,感谢您的帮助。