golang实现ping功能

使用golang实现ping功能

func ping(ip string) error {
	// 解析目标 IP 地址
	dst, err := net.ResolveIPAddr("ip4", ip)
	if err != nil {
		return fmt.Errorf("解析 IP 地址失败: %w", err)
	}

	// 创建 ICMP 连接
	conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
	if err != nil {
		return fmt.Errorf("无法创建 ICMP 连接: %w", err)
	}
	defer conn.Close()

	// 构造 ICMP Echo 请求
	msg := icmp.Message{
		Type: ipv4.ICMPTypeEcho, Code: 0,
		Body: &icmp.Echo{
			ID:   os.Getpid() & 0xffff, // ICMP ID 可以使用进程 ID
			Seq:  1,
			Data: []byte("HELLO-R-U-THERE"),
		},
	}

	// 序列化 ICMP 请求
	msgBytes, err := msg.Marshal(nil)
	if err != nil {
		return fmt.Errorf("ICMP 请求序列化失败: %w", err)
	}

	// 设置超时时间
	if err := conn.SetDeadline(time.Now().Add(2 * time.Second)); err != nil {
		return fmt.Errorf("设置超时失败: %w", err)
	}

	// 发送 ICMP 请求到目标 IP
	_, err = conn.WriteTo(msgBytes, dst)
	if err != nil {
		return fmt.Errorf("发送 ICMP 请求失败: %w", err)
	}

	// 接收 ICMP 响应
	reply := make([]byte, 1500)
	n, _, err := conn.ReadFrom(reply)
	if err != nil {
		return fmt.Errorf("接收 ICMP 响应失败: %w", err)
	}

	// 解析 ICMP 响应
	resp, err := icmp.ParseMessage(ipv4.ICMPTypeEcho.Protocol(), reply[:n])
	if err != nil {
		return fmt.Errorf("解析 ICMP 响应失败: %w", err)
	}

	// 检查响应类型是否为 Echo Reply
	if resp.Type == ipv4.ICMPTypeEchoReply {
		return nil
	}
	return fmt.Errorf("非预期的 ICMP 响应: %v", resp)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值