2010-05-30 83 views

回答

5

目前,Go net软件包不支持ICMP Echo(Ping)功能。

有没有支持发送ICMP 回声请求。你必须添加 支持包网络。 ping

+2

Go(自2010年5月底起),Go支持原始套接字(请参阅net.IPConn类型) - 意思是您可以实现ement ping自己 - 并且在https://code.google.com/p/go/source/browse/src/pkg/net/ipraw_test.go有一个ping示例 – nos 2010-07-23 20:41:47

+0

@nos链接不起作用。新的URL应该是:https://golang.org/src/net/ipraw_test.go – TheHippo 2015-04-08 14:46:42

9

下面的代码说明了如何使用原始套接字执行ping在IPv4(需要根PRIVS):基于示例

package main 

import (
    "log" 
    "net" 
    "os" 

    "golang.org/x/net/icmp" 
    "golang.org/x/net/internal/iana" 
    "golang.org/x/net/ipv4" 
) 

const targetIP = "8.8.8.8" 

func main() { 
    c, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0") 
    if err != nil { 
     log.Fatalf("listen err, %s", err) 
    } 
    defer c.Close() 

    wm := icmp.Message{ 
     Type: ipv4.ICMPTypeEcho, Code: 0, 
     Body: &icmp.Echo{ 
      ID: os.Getpid() & 0xffff, Seq: 1, 
      Data: []byte("HELLO-R-U-THERE"), 
     }, 
    } 
    wb, err := wm.Marshal(nil) 
    if err != nil { 
     log.Fatal(err) 
    } 
    if _, err := c.WriteTo(wb, &net.IPAddr{IP: net.ParseIP(targetIP)}); err != nil { 
     log.Fatalf("WriteTo err, %s", err) 
    } 

    rb := make([]byte, 1500) 
    n, peer, err := c.ReadFrom(rb) 
    if err != nil { 
     log.Fatal(err) 
    } 
    rm, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n]) 
    if err != nil { 
     log.Fatal(err) 
    } 
    switch rm.Type { 
    case ipv4.ICMPTypeEchoReply: 
     log.Printf("got reflection from %v", peer) 
    default: 
     log.Printf("got %+v; want echo reply", rm) 
    } 
} 

代码在这里找到:https://godoc.org/golang.org/x/net/icmp#PacketConn

为了作为非特权用户从Linux进行ping操作,请参阅this post

+0

现在,ICMP(1)的IANA号码不能通过'iana.ProtocolICMP'访问,但可以通过'ipv4访问。 ICMPTypeEcho.Protocol()'。 “golang.org/x/net/internal/iana”包是内部的,使用go 1.8编译器时说:“不允许使用内部包”cf:https://godoc.org/golang.org/x /net/ipv4#ICMPType.Protocol – TPPZ 2017-09-05 16:11:15

+0

也参阅。 https://godoc.org/golang.org/x/net/internal/iana – TPPZ 2017-09-05 16:19:05