如何将TCP连接对象传递给其他Go模块?

时间:2014-03-19 21:11:19

标签: map tcp go gob

我有一个连接主机名的地图,我试图将其传递给我在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是零,这引起了恐慌。对不起,感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

更新:问题被发现了!我没有意识到你可以通过fmt.Println(conn)从中获取更多信息,并发现conn是零,这引起了恐慌。对不起,感谢您的帮助。