o2o分销系统网站建设,网站用户运营,什么是长尾关键词举例,怎样编写网站熟悉报文结构 ICMP校验和算法#xff1a;
报文内容#xff0c;相邻两个字节拼接到一起组成一个16bit数#xff0c;将这些数累加求和若长度为奇数#xff0c;则将剩余一个字节#xff0c;也累加求和得出总和之后#xff0c;将和值的高16位与低16位不断求和#xff0c;直…熟悉报文结构 ICMP校验和算法
报文内容相邻两个字节拼接到一起组成一个16bit数将这些数累加求和若长度为奇数则将剩余一个字节也累加求和得出总和之后将和值的高16位与低16位不断求和直到高16位为0以上三步得出结果后取反即为验证和 我们选取实现其中的
先实现命令行部分
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 (bytesencoding/binaryflagfmtlognetostime
)// 定义全局变量
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[index1])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 (bytesencoding/binaryflagfmtlogmathnetostime
)// 定义全局变量
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 {sendCountt1 : 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 {failCountlog.Println(err)continue}// 接收ICMP响应buf : make([]byte, 65535)n, err conn.Read(buf)if err ! nil {failCountlog.Println(err)continue}successCountts : 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[index1])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)
}
成功