du2229 2014-03-19 21:11
浏览 71

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

I have a map of hostnames to connections that I am trying to pass around to different modules for an application that I am writing in Go.

var conns_ map[string]net.Conn // tcp connections per node

In the main server.go file, I dial the other servers in my network and save the connections to this map:

conn, err := net.Dial("tcp", address)
conns_[hostname] = conn

Then I want to send this map to other modules to re-use the connections. Here is an example for how I send it to the learner module:

go learner.ListenForNotifies(conns_, selfname_)

In the learner module I take the map and start trying to use a gob.Decoder on each connection that it contains:

func ListenForNotifies(conns map[string]net.Conn, selfname string) {
    for hostname, conn := range conns {
        go listen(hostname, conn, lChan)
    }
    // etc.
}

And within the listen function:

func listen(hostname string, conn net.Conn, lChan chan string) {
    decoder := gob.NewDecoder(conn)
    proposal := &utils.Proposal{}
    err := decoder.Decode(proposal)
    // etc.
}

The problem is that when I call decoder.Decode(proposal) here, a panic happens:

panic: runtime error: invalid memory address or nil pointer dereference

I use this same encode/decode code elsewhere without problems, and the only difference is that I'm trying to re-use a connection instead of calling decode immediately after establishing a new one within the same function. I've been trying to make this work for hours, trying to pass things by reference, using map[string]interface{}, and all sorts of things without luck. Gob.decode should block until something is encoded on the underlying net.Conn object, right? I can only guess that the net.Conn object has gotten invalidated somehow by this point.

Am I doing something wrong with how I am passing around connection objects? I read that a net.Conn was a very simple object that was fine to pass by value, but I must be missing something. When attempting to pass it by reference using type interface{}, I got errors like:

interface {} does not implement net.Conn (missing Close method)

I'm at a loss now, trying to figure out what could be wrong with the connection objects, if I'm misusing gob.Decode, there's an issue with putting net.Conn objects into maps, or if the problem is something completely different.

Any ideas?

edit: The full panic traceback is below:

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

Update: The problem was found! I didn't realize that you could just fmt.Println(conn) to get more information out of it, and discovered that the conn was nil, and that caused the panic. Sorry for the trouble, and thanks for your help.

  • 写回答

1条回答 默认 最新

  • dongsong8932 2014-03-20 10:13
    关注

    Update: The problem was found! I didn't realize that you could just fmt.Println(conn) to get more information out of it, and discovered that the conn was nil, and that caused the panic. Sorry for the trouble, and thanks for your help.

    评论

报告相同问题?

悬赏问题

  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大