如何监听ICMP数据包?

kki*_*che 4 sockets network-programming listener go icmp

我正在开发一个两部分应用程序,其中一方发送ICMP数据包,另一方侦听ICMP数据包并在收到它们时采取行动.问题是,我不确定如何让监听器无限期地保持活着(只是希望它坐在循环中,只在收到数据包时才采取行动).

目前,我能够使用go-fastping库,如果是双向通信,我可以发送和接收数据包(我发送它,它们响应,我处理远程响应).问题是如何使这种不对称?

我对听众的尝试是:

for {
    conn, err := icmp.ListenPacket("ip4:icmp", "192.168.1.8")
    if err != nil {
        fmt.Println(err)
    }
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用.我的逻辑是我想要一个while true循环来保持监听器活着(在这种情况下就是这样for {),然后我用ICMP监听新的数据包,ListenPacket但我似乎没有使用这种方法得到任何东西.

任何想法或帮助将不胜感激.提前感谢您的时间和帮助.

Sat*_*Rai 7

icmp.ListenPacket()创造一个*icmp.PacketConn- 换句话说,一个听众.您正在无限循环中创建侦听器!由于你甚至没有关闭它们,你的程序会开始抱怨too many open files比你说"ping"更快.

以下是工作监听器的示例

package main

import (
    "golang.org/x/net/icmp"
    "log"
)

func main() {
    conn, err := icmp.ListenPacket("ip4:icmp", "192.168.0.12")
    if err != nil {
        log.Fatal(err)
    }

    for {
        var msg []byte
        length, sourceIP, err := conn.ReadFrom(msg)
        if err != nil {
            log.Println(err)
            continue
        }

        log.Printf("message = '%s', length = %d, source-ip = %s", string(msg), length, sourceIP)
    }
    _ = conn.Close()
}
Run Code Online (Sandbox Code Playgroud)

这会产生:

2015/10/26 10:35:00 message = '', length = 0, source-ip = 192.168.0.7
2015/10/26 10:35:00 message = '', length = 0, source-ip = 192.168.0.25
2015/10/26 10:35:01 message = '', length = 0, source-ip = 192.168.0.7
2015/10/26 10:35:01 message = '', length = 0, source-ip = 192.168.0.25
2015/10/26 10:35:02 message = '', length = 0, source-ip = 192.168.0.7
2015/10/26 10:35:02 message = '', length = 0, source-ip = 192.168.0.25
Run Code Online (Sandbox Code Playgroud)

我同时从2个主机ping主机.

如果需要,您可以选择丢弃传入消息和其他返回值.