2016-07-25 193 views
0

我是一个Golang的新手,想要做一些非常简单的任务 - 发送ping一些文本并在回复时读取文本,但是我我遇到了一些我不明白的事情。我已经建立了一个ping这样的:解析golang中的icmp消息时出现的问题

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)) 

围棋是不是在构建时光:

./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是非常高兴地编译和运行该代码。有人可以告诉我为什么类型开关中的代码工作正常,但第一个例子会导致编译错误。谢谢!

回答

1

message.BodyMessageBodyhttps://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 
} 

谨防恐慌。