2016-07-25 3 views
0

Я новичок в Golang и пытаюсь сделать то, что кажется очень простой задачей - отправка пинга с некоторым текстом в нем и чтение этого текста обратно, когда я получаю ответ, но я «Я сталкиваюсь с некоторыми вещами, которые я не понимаю. Я построил пинг, как это:Устранение неполадок сообщений icmp в golang

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 совершенно счастлив скомпилировать и запустить этот код. Может кто-то сказать мне, почему код в коммутаторе типов работает нормально, но первый пример приводит к ошибкам компиляции. Спасибо!

ответ

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 
} 

для защиты от паники.

Смежные вопросы