当前位置: 首页 > news >正文

Golang云原生项目:—实现ping操作

熟悉报文结构

在这里插入图片描述
ICMP校验和算法:

  1. 报文内容,相邻两个字节拼接到一起组成一个16bit数,将这些数累加求和
  2. 若长度为奇数,则将剩余一个字节,也累加求和
  3. 得出总和之后,将和值的高16位与低16位不断求和,直到高16位为0
  4. 以上三步得出结果后,取反,即为验证和

在这里插入图片描述
我们选取实现其中的

先实现命令行部分

var (timeout int64size    intcount   int
)func getCommandArgs() {//通过flag.来读命令行的参数flag.Int64Var(&timeout, "w", 1000, "请求超时时长,单位毫秒")flag.IntVar(&size, "l", 32, "请求发送缓冲区大小,单位字节")flag.IntVar(&count, "n", 4, "发送请求数")flag.Parse()}
func main() {getCommandArgs()fmt.Println(timeout, size, count)
}

在这里插入图片描述

测试显示,可以成功拿到命令行的参数
在这里插入图片描述
定义ICMP报文格式

type ICMP struct{Type    	uint8Code	    uint8Checksum 	uint16ID 			uint16SequenceNum uint16
}

全部代码加注释

package mainimport ("bytes""encoding/binary""flag""fmt""log""net""os""time"
)// 定义全局变量
var (timeout int64     // 请求超时时长,单位毫秒size    int       // 请求发送缓冲区大小,单位字节count   int       // 发送请求数typ     uint8 = 8 // ICMP请求类型code    uint8 = 0 // ICMP请求代码
)// ICMP结构体定义ICMP请求的数据结构
type ICMP struct {Type        uint8Code        uint8Checksum    uint16ID          uint16SequenceNum uint16
}func main() {getCommandArgs() // 获取命令行参数// 取出最后一个参数,即目标IP地址desIp := os.Args[len(os.Args)-1]// 建立ICMP连接conn, err := net.DialTimeout("ip:icmp", desIp, time.Duration(timeout)*time.Millisecond)if err != nil {// 如果连接建立失败,直接返回log.Fatal(err)return}defer conn.Close()// 打印Ping信息fmt.Printf(" 正在Ping %s [%s] 具有 %d 字节的数据:\n", desIp, conn.RemoteAddr(), size)// 发送ICMP请求并接收响应for i := 0; i < count; i++ {t1 := time.Now() // 记录发送时间icmp := &ICMP{Type:        typ,Code:        code,Checksum:    0,ID:          1,SequenceNum: 1,}// 构造ICMP请求数据data := make([]byte, size)var buffer bytes.Bufferbinary.Write(&buffer, binary.BigEndian, icmp)buffer.Write(data)data = buffer.Bytes()// 计算校验和checkSum := checkSum(data)data[2] = byte(checkSum >> 8) // 高位data[3] = byte(checkSum & 0xff)// 设置超时时间conn.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Millisecond))// 发送ICMP请求n, err := conn.Write(data)if err != nil {log.Println(err)continue}// 接收ICMP响应buf := make([]byte, 65535)n, err = conn.Read(buf)if err != nil {log.Println(err)continue}ts := time.Since(t1).Milliseconds() // 计算响应时间fmt.Printf("来自 %d.%d.%d.%d 的回复: 字节=%d 时间=%dms TTL=%d\n", buf[12], buf[13], buf[14], buf[15], n-28, ts, buf[8])time.Sleep(time.Second) // 等待1秒再次发送}
}// getCommandArgs函数用于解析命令行参数
func getCommandArgs() {flag.Int64Var(&timeout, "w", 1000, "请求超时时长,单位毫秒")flag.IntVar(&size, "l", 32, "请求发送缓冲区大小,单位字节")flag.IntVar(&count, "n", 4, "发送请求数")flag.Parse()
}// checkSum函数用于计算ICMP请求的校验和
func checkSum(data []byte) uint16 {length := len(data)index := 0var sum uint32 = 0for length > 1 {sum += uint32(data[index])<<8 + uint32(data[index+1])length -= 2index += 2}if length != 0 {sum += uint32(data[index])}hi16 := (sum >> 16)for hi16 != 0 {sum = hi16 + uint32(uint16(sum))hi16 = (sum >> 16)}return uint16(^sum)
}

好好看

记住,运行时需要以管理员身份,才能解析socket

使用

go run .\main.go -w 150 -l 32 -n 8 www.baidu.com

测试

在这里插入图片描述
成功!

继续优化
把累计结果加上

package mainimport ("bytes""encoding/binary""flag""fmt""log""math""net""os""time"
)// 定义全局变量
var (timeout      int64     // 请求超时时长,单位毫秒size         int       // 请求发送缓冲区大小,单位字节count        int       // 发送请求数typ          uint8 = 8 // ICMP请求类型code         uint8 = 0 // ICMP请求代码sendCount    intsuccessCount intfailCount    intminTs        int64 = math.MaxInt64maxTs        int64totalTs      int64
)// ICMP结构体定义ICMP请求的数据结构
type ICMP struct {Type        uint8Code        uint8Checksum    uint16ID          uint16SequenceNum uint16
}func main() {getCommandArgs() // 获取命令行参数// 取出最后一个参数,即目标IP地址desIp := os.Args[len(os.Args)-1]// 建立ICMP连接conn, err := net.DialTimeout("ip:icmp", desIp, time.Duration(timeout)*time.Millisecond)if err != nil {// 如果连接建立失败,直接返回log.Fatal(err)return}defer conn.Close()// 打印Ping信息fmt.Printf(" 正在Ping %s [%s] 具有 %d 字节的数据:\n", desIp, conn.RemoteAddr(), size)// 发送ICMP请求并接收响应for i := 0; i < count; i++ {sendCount++t1 := time.Now() // 记录发送时间icmp := &ICMP{Type:        typ,Code:        code,Checksum:    0,ID:          1,SequenceNum: 1,}// 构造ICMP请求数据data := make([]byte, size)var buffer bytes.Bufferbinary.Write(&buffer, binary.BigEndian, icmp)buffer.Write(data)data = buffer.Bytes()// 计算校验和checkSum := checkSum(data)data[2] = byte(checkSum >> 8) // 高位data[3] = byte(checkSum & 0xff)// 设置超时时间conn.SetDeadline(time.Now().Add(time.Duration(timeout) * time.Millisecond))// 发送ICMP请求n, err := conn.Write(data)if err != nil {failCount++log.Println(err)continue}// 接收ICMP响应buf := make([]byte, 65535)n, err = conn.Read(buf)if err != nil {failCount++log.Println(err)continue}successCount++ts := time.Since(t1).Milliseconds() // 计算响应时间if minTs > ts {minTs = ts}if maxTs < ts {maxTs = ts}totalTs += tsfmt.Printf("来自 %d.%d.%d.%d 的回复: 字节=%d 时间=%dms TTL=%d\n", buf[12], buf[13], buf[14], buf[15], n-28, ts, buf[8])time.Sleep(time.Second) // 等待1秒再次发送}//统计信息fmt.Printf("%s 的 Ping 统计信息:\n数据包: 已发送 = %d,已接收 = %d,丢失 = %d (%.2f%% 丢失),\n往返行程的估计时间(以毫秒为单位):\n最短 = %dms,最长 = %dms,平均 = %dms",conn.RemoteAddr(), sendCount, successCount, failCount, float64(failCount)/float64(sendCount)*100, minTs, maxTs, totalTs/int64(sendCount))}// getCommandArgs函数用于解析命令行参数
func getCommandArgs() {flag.Int64Var(&timeout, "w", 1000, "请求超时时长,单位毫秒")flag.IntVar(&size, "l", 32, "请求发送缓冲区大小,单位字节")flag.IntVar(&count, "n", 4, "发送请求数")flag.Parse()
}// checkSum函数用于计算ICMP请求的校验和
func checkSum(data []byte) uint16 {length := len(data)index := 0var sum uint32 = 0for length > 1 {sum += uint32(data[index])<<8 + uint32(data[index+1])length -= 2index += 2}if length != 0 {sum += uint32(data[index])}hi16 := (sum >> 16)for hi16 != 0 {sum = hi16 + uint32(uint16(sum))hi16 = (sum >> 16)}return uint16(^sum)
}

成功

在这里插入图片描述

相关文章:

Golang云原生项目:—实现ping操作

熟悉报文结构 ICMP校验和算法&#xff1a; 报文内容&#xff0c;相邻两个字节拼接到一起组成一个16bit数&#xff0c;将这些数累加求和若长度为奇数&#xff0c;则将剩余一个字节&#xff0c;也累加求和得出总和之后&#xff0c;将和值的高16位与低16位不断求和&#xff0c;直…...

mysql如何查看当前事务的事务id

-- 开启一个事务&#xff0c;但不执行写操作 START TRANSACTION; -- 查询 InnoDB 事务信息 SELECT * FROM information_schema.innodb_trx;在 MySQL 的 MVCC (多版本并发控制) 中&#xff0c;事务 ID (Transaction ID) 是由 InnoDB 存储引擎分配的&#xff0c;它的分配机制与事…...

在linux里如何利用vim对比两个文档不同的行数

在Linux中&#xff0c;可以使用vimdiff命令来对比两个文档中不同的行。首先确保你的系统中安装了vim编辑器。 打开终端&#xff0c;使用以下命令来启动vimdiff&#xff1a; vimdiff file1 file2 这里file1和file2是你想要对比的两个文件的路径。 vimdiff会以并排方式打开两…...

深入解析Python中的逻辑回归:从入门到精通

引言 在数据科学领域&#xff0c;逻辑回归&#xff08;Logistic Regression&#xff09;是一个非常重要的算法&#xff0c;它不仅用于二分类问题&#xff0c;还可以通过一些技巧扩展到多分类问题。逻辑回归因其简单、高效且易于解释的特点&#xff0c;在金融、医疗、广告等多个…...

【数据库】mysql数据库迁移前应如何备份数据?

MySQL 数据库的备份是确保数据安全的重要措施之一。在进行数据库迁移之前&#xff0c;备份现有数据可以防止数据丢失或损坏。以下是一套详细的 MySQL 数据库备份步骤&#xff0c;适用于大多数情况。请注意&#xff0c;具体的命令和工具可能因 MySQL 版本的不同而有所差异。整个…...

C语言——鸡兔同笼问题

没注释的源代码 #include <stdio.h> #include <stdlib.h> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ int main(int argc, char *argv[]) { int tou 10; i…...

数据结构王道P234第二题

#include<iostream> using namespace std; int visit[MAxsize]; int color[MaxSize];//1表示红&#xff0c;2表示白&#xff1b; bool dfs(Graph G, int i){visit[i]1;ArcNode *p;bool flag1;for(pG.vertices[i].firsrarc; p ; pp->next){int jp->adjvex;if(!visi…...

层归一化和批归一化

层归一化是针对某一样本的所有特征&#xff0c;批归一化是针对所有样本的某一特征。 计算公式&#xff1a;&#xff08;当前值 - 均值&#xff09;/ 标准差。 作用&#xff1a;缓解梯度消失和梯度爆炸的问题&#xff0c;并提高网络的泛化性能。 为什么Transform和BERT中使用层归…...

Spring Cloud Gateway 网关

微服务网关 Spring Cloud Gateway https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories Spring Cloud 在版本 2020.0.0 开始&#xff0c;去除了 Zuul 网关的使用&#xff0c;改用 Spring Cloud Gateway 作为网关…...

LabVIEW中的UDP与TCP比较

在LabVIEW中&#xff0c;UDP和TCP可以用于不同的网络通信场景&#xff0c;开发者可以根据需求选择合适的协议。以下是结合LabVIEW开发时的一些比较和应用场景&#xff1a; 1.TCP在LabVIEW中的应用&#xff1a; 可靠性高的场景&#xff1a;当开发一个对数据传输的准确性和完整…...

半导体器件与物理篇3 P-N结

热平衡时的PN结 pn结的定义&#xff1a;由p型半导体和n型半导体接触形成的结 pn结的特性和关键变量包括&#xff1a;整流性&#xff08;即电流单向导通的特性&#xff09;、平衡费米能级&#xff08;费米能级 E F E_F EF​为常数, d E F d x 0 &#xff09;、内建电势 \frac…...

深入剖析String类的底层实现原理

嘿嘿,家人们,今天咱们来模拟实现string,好啦,废话不多讲,开干! 1:string.h 1.1:构造函数与拷贝构造函数 1.1.1:写法一 1.1.2:写法二(给缺省值) 1.2:赋值运算符重载与operatror[]获取元素 1.3:容量与迭代器 1.4:reserve与resize 1.5:清空与判断是否为空 1.6:push_back与…...

#其它:面试题

第一面试官提问如下&#xff1a; 1、自我介绍 2、根据项目提问&#xff1a;混合开发调取api的通讯方式 3、技术提问&#xff1a;如何隐藏div&#xff0c;但是div需要存在 使用 visibility 隐藏&#xff1a; 1.visibility: hidden2.display: none 3.opcity: 04、css塌陷问题…...

计算机视觉中的双边滤波:经典案例与Python代码解析

&#x1f31f; 计算机视觉中的双边滤波&#xff1a;经典案例与Python代码解析 &#x1f680; Hey小伙伴们&#xff01;今天我们要聊的是计算机视觉中的一个重要技术——双边滤波。双边滤波是一种非线性滤波方法&#xff0c;主要用于图像去噪和平滑&#xff0c;同时保留图像的边…...

【AI日记】24.11.17 看 GraphRAG 论文,了解月之暗面

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 核心工作 内容&#xff1a;看 GraphRAG 论文时间&#xff1a;4 小时评估&#xff1a;不错&#xff0c;继续 非核心工作 内容&#xff1a;了解国内大模型方向&#xff0c;重点了解了创业独角兽-月之暗面&…...

Front Panel Window Bounds 与 Front Panel Window Bounds 的区别与应用

在LabVIEW中&#xff0c;Front Panel Window Bounds 和 Front Panel WindowBounds 是两个不同的属性节点&#xff0c;用于描述前面板窗口的位置和大小。它们的区别主要体现在它们表示的是窗口的不同部分&#xff0c;具体如下&#xff1a; 1 Window Bounds&#xff1a;调整整个…...

比较TCP/IP和OSI/RM的区别

一、结构不同 1、OSI&#xff1a;OSI划分为7层结构&#xff1a;物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。 2、TCP/IP&#xff1a;TCP/IP划分为4层结构&#xff1a;应用层、传输层、互联网络层和主机-网络层。 二、性质不同 1、OSI&#xff1a;OSI是制定…...

【Java项目】基于SpringBoot的【招聘信息管理系统】

技术简介&#xff1a;系统软件架构选择B/S模式、SpringBoot框架、java技术和MySQL数据库等&#xff0c;总体功能模块运用自顶向下的分层思想。 系统简介&#xff1a;招聘信息管理系统的功能分为管理员&#xff0c;用户和企业三个部分&#xff0c;系统的主要功能包括首页、个人中…...

【论文笔记】LLaMA-VID: An Image is Worth 2 Tokens in Large Language Models

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: LLaMA-VID: An Image is W…...

使用Web Storage API实现客户端数据持久化

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用Web Storage API实现客户端数据持久化 使用Web Storage API实现客户端数据持久化 使用Web Storage API实现客户端数据持久化…...

10分钟上手!Java开发者也能轻松调用AI,Spring AI Alibaba手把手教你构建智能体!

介绍&#xff1a;还在羡慕Python开发者能轻松调用AI&#xff1f;Spring AI Alibaba让Java也能10分钟构建一个能“思考”和“行动”的智能体&#xff0c;这次手把手教&#xff01; 系统&#xff1a;Windows jdk版本&#xff1a;17 maven&#xff1a;3.8 模型API Key&#xff1a…...

vLLM-v0.17.1惊艳效果:束搜索+并行采样在长文本生成中的稳定性展示

vLLM-v0.17.1惊艳效果&#xff1a;束搜索并行采样在长文本生成中的稳定性展示 1. vLLM框架核心能力概览 vLLM是一个专为大型语言模型(LLM)设计的高性能推理和服务库&#xff0c;其最新版本v0.17.1在长文本生成稳定性方面取得了显著突破。这个开源项目最初由加州大学伯克利分校…...

Ubuntu16.04服务器上从零部署LaneNet车道线检测:Tusimple数据集处理全流程避坑指南

Ubuntu 16.04服务器部署LaneNet车道线检测全流程实战 在自动驾驶和智能交通系统中&#xff0c;车道线检测是一项基础而关键的技术。本文将详细介绍如何在Ubuntu 16.04服务器环境下&#xff0c;从零开始部署LaneNet车道线检测模型&#xff0c;并处理Tusimple数据集的全流程。不同…...

24小时运行验证:OpenClaw+ollama-QwQ-32B自动化监控脚本稳定性测试

24小时运行验证&#xff1a;OpenClawollama-QwQ-32B自动化监控脚本稳定性测试 1. 项目背景与目标设定 去年冬天的一个深夜&#xff0c;我被手机警报惊醒——某个关键商品的价格突然跌破了我的心理预期。手忙脚乱登录电商平台时&#xff0c;优惠早已结束。这次经历让我意识到&…...

终极指南:GoldHEN Cheats Manager - PlayStation 4游戏作弊代码完整管理方案

终极指南&#xff1a;GoldHEN Cheats Manager - PlayStation 4游戏作弊代码完整管理方案 【免费下载链接】GoldHEN_Cheat_Manager GoldHEN Cheats Manager 项目地址: https://gitcode.com/gh_mirrors/go/GoldHEN_Cheat_Manager GoldHEN Cheats Manager 是一款专为PlaySt…...

DeOldify开源贡献指南:如何参与项目改进与代码提交

DeOldify开源贡献指南&#xff1a;如何参与项目改进与代码提交 想为DeOldify这个酷炫的图片上色项目添砖加瓦&#xff0c;但又觉得开源贡献这事儿门槛太高&#xff0c;不知道从何下手&#xff1f;别担心&#xff0c;你绝对不是一个人。很多人对开源既向往又畏惧&#xff0c;总…...

DataGuard运维避坑指南:当备库遇到ORA-01578坏块时的完整恢复流程

DataGuard运维实战&#xff1a;备库ORA-01578坏块诊断与FROM SERVICE精准修复 凌晨三点&#xff0c;当告警短信突然亮起"ORA-01578: ORACLE data block corrupted"的红色提示时&#xff0c;作为DBA的你很清楚这意味着什么——这不仅是简单的坏块问题&#xff0c;更是…...

6大终极方案!WarcraftHelper全方位解决魔兽争霸III在Win10/11兼容性难题

6大终极方案&#xff01;WarcraftHelper全方位解决魔兽争霸III在Win10/11兼容性难题 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 经典游戏魔兽争霸…...

智能工单管理系统 2026 怎么挑?五款热门平台对比,适配企业各类业务场景

工单智能化应用&#xff1a;帮您告别工单苦海 传统工单系统的痛点&#xff0c;本质是信息处理效率与用户体验的矛盾。随着AI 的发展&#xff0c;工单智能化应用的核心逻辑转变为&#xff0c;通过AI技术将“人找信息”转变为“信息找人”&#xff0c;甚至“预测需求”。 工单管…...

1949–2024年中国县级行政区划(逐年)|全国范围、75年连续、SHP格式

&#x1f50d; 数据简介 本数据集完整覆盖 1949年至2024年 共 76个年份 的中国县级行政区划边界&#xff0c;是目前公开可获取的时间跨度最长、更新粒度最细的全国县级历史区划产品。 每一年份均提供独立、闭合、无重叠的面状矢量边界&#xff0c;属性表包含标准名称、行政区划…...