用Go实现Ping操作
本帖最后由 Shaw0xyz 于 2024-5-18 20:12 编辑在Go语言中实现一个Ping操作可以通过使用ICMP协议。Go的标准库中没有直接提供Ping操作的库,但可以使用第三方库,例如`golang.org/x/net/icmp`和`golang.org/x/net/ipv4`,来实现。
以下是一个简单的示例,演示如何在Go中实现Ping操作:
package main
import (
"encoding/binary"
"fmt"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"net"
"os"
"time"
)
func main() {
if len(os.Args) != 2 {
fmt.Printf("Usage: %s <host>\n", os.Args)
os.Exit(1)
}
target := os.Args
addr, err := net.ResolveIPAddr("ip4", target)
if err != nil {
fmt.Printf("Failed to resolve %s: %v\n", target, err)
os.Exit(1)
}
conn, err := net.DialIP("ip4:icmp", nil, addr)
if err != nil {
fmt.Printf("Failed to dial: %v\n", err)
os.Exit(1)
}
defer conn.Close()
// Create ICMP Echo Request packet
icmpEcho := icmp.Message{
Type: ipv4.ICMPTypeEcho,
Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff,
Seq:1,
Data: []byte("PING"),
},
}
// Serialize ICMP message
msg, err := icmpEcho.Marshal(nil)
if err != nil {
fmt.Printf("Failed to marshal ICMP message: %v\n", err)
os.Exit(1)
}
// Send ICMP Echo Request
start := time.Now()
_, err = conn.Write(msg)
if err != nil {
fmt.Printf("Failed to send ICMP message: %v\n", err)
os.Exit(1)
}
// Receive ICMP Echo Reply
reply := make([]byte, 1500)
err = conn.SetReadDeadline(time.Now().Add(10 * time.Second))
if err != nil {
fmt.Printf("Failed to set read deadline: %v\n", err)
os.Exit(1)
}
n, err := conn.Read(reply)
if err != nil {
fmt.Printf("Failed to read ICMP message: %v\n", err)
os.Exit(1)
}
duration := time.Since(start)
// Parse ICMP message
parsedMsg, err := icmp.ParseMessage(1, reply[:n])
if err != nil {
fmt.Printf("Failed to parse ICMP message: %v\n", err)
os.Exit(1)
}
switch parsedMsg.Type {
case ipv4.ICMPTypeEchoReply:
echoReply, ok := parsedMsg.Body.(*icmp.Echo)
if !ok {
fmt.Println("Received unexpected ICMP message body")
os.Exit(1)
}
fmt.Printf("Received ICMP Echo Reply from %s: id=%d seq=%d time=%v\n", addr, echoReply.ID, echoReply.Seq, duration)
default:
fmt.Printf("Received unexpected ICMP message type %v\n", parsedMsg.Type)
}
}
运行此代码的步骤:
1. 安装依赖包:
go get golang.org/x/net/icmp
go get golang.org/x/net/ipv4
2. 保存代码到一个文件,如`ping.go`。
3. 运行代码:
go run ping.go example.com
代码说明:
1. 解析目标地址:通过`net.ResolveIPAddr`解析目标主机的IP地址。
2. 建立连接:使用`net.DialIP`建立到目标主机的ICMP连接。
3. 构造ICMP请求:创建一个ICMP Echo Request消息,并将其序列化为字节数组。
4. 发送请求:通过连接发送ICMP Echo Request。
5. 接收响应:读取从目标主机返回的ICMP Echo Reply,并解析响应消息。
6. 显示结果:显示响应的详细信息,包括响应时间。
这个示例演示了如何使用Go语言进行Ping操作,通过发送ICMP Echo Request并接收Echo Reply来测量目标主机的响应时间。
页:
[1]