【问题标题】:Trouble parsing icmp messages in golang在 golang 中解析 icmp 消息时遇到问题
【发布时间】:2016-07-25 02:56:56
【问题描述】:

我是 Golang 的新手,正在尝试做一个看似非常简单的任务——发送一个包含一些文本的 ping,并在我收到回复时读回该文本,但我遇到了一些事情我不明白。我已经建立了这样的 ping:

 ping := icmp.Message{
    Type: ipv4.ICMPTypeEcho,
    Code: 0,
    Body: &icmp.Echo{
        ID: os.Getpid() & 0xffff,
        Seq: 1,
        Data: []byte("Hello"),
    },
}

这是上下文的套接字读取部分:

buf := make([]byte, 1500)
_, peer, err := c.ReadFrom(buf)
message, err := icmp.ParseMessage(1, buf)

这是我从邮件正文中取回数据的失败尝试:

body := message.Body;
fmt.Println("body.ID ", body.ID)
fmt.Println("body.Seq ", body.Seq)
fmt.Println("body.Data ", string(body.Data))

Go 在构建时不开心:

./ping.go:86: body.ID undefined (type icmp.MessageBody has no field or method ID)
./ping.go:87: body.Seq undefined (type icmp.MessageBody has no field or method Seq)
./ping.go:88: body.Data undefined (type icmp.MessageBody has no field or method Data)

然而,这段改编自 this awesome project 的代码非常有效:

switch body := message.Body.(type) {
  case *icmp.Echo:
    fmt.Println("body.ID ", body.ID)
    fmt.Println("body.Seq ", body.Seq)
    fmt.Println("body.Data ", string(body.Data))
  default:
    fmt.Println("not a *icmp.Echo")
}

Go 非常乐意编译和运行这段代码。有人可以告诉我为什么类型开关中的代码可以正常工作,但是第一个示例会导致编译错误。谢谢!

【问题讨论】:

    标签: go icmp


    【解决方案1】:

    message.Body 是一个MessageBody (https://godoc.org/golang.org/x/net/icmp#MessageBody),它是一个接口类型。如果你想要底层类型,你需要强制转换它。一种方法是说

    body := message.Body.(*icmp.Echo)
    ...
    

    这可能对你有用,但如果MessageBody 不是icmp.Echo 指针,那么它将会是一个恐慌。

    类型开关确保没有恐慌。

    你也可以

    if body, ok := message.Body.(*icmp.Echo); ok {
        // do something with Body as an *icmp.Echo type
    }
    

    防止恐慌。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-24
      • 2011-03-16
      • 2016-04-06
      • 1970-01-01
      相关资源
      最近更新 更多