douben8492 2016-07-25 02:56
浏览 148
已采纳

无法在Golang中解析icmp消息

I'm a newb with Golang and trying to do what seems like a very simple task -- sending a ping with some text in it and reading that text back when I get a reply, but I'm running into some things I don't understand. I've built a ping like this:

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

Here's the socket read part for context:

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

Here's my failed effort to get my data back out of the message body:

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

Go is not happy at build time:

./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 code, however, which is adapted from this awesome project, works just swell:

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 is perfectly happy to compile and run this code. Can someone tell me why the code in the type switch works fine, but the first example results in compile errors. Thank you!

  • 写回答

1条回答 默认 最新

  • douji7399 2016-07-25 06:06
    关注

    message.Body is a MessageBody (https://godoc.org/golang.org/x/net/icmp#MessageBody) which is an interface type. If you want the underlying type you need to cast it. One way to do that would be to say

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

    This would likely work for you, but if the MessageBody is NOT an icmp.Echo pointer then it will be a panic.

    The type switch makes sure there is no panic.

    You could also do

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

    to guard against the panic.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求解 yolo算法问题
  • ¥15 虚拟机打包apk出现错误
  • ¥30 最小化遗憾贪心算法上界
  • ¥15 用visual studi code完成html页面
  • ¥15 聚类分析或者python进行数据分析
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝