go實(shí)現(xiàn)fping功能
1、什么是fping
fping 是一個(gè)類似 ping 的程序,與 ping 不同的是你可以同時(shí)指定多個(gè)要 ping 的目標(biāo)。
fping 發(fā)送完 ping 包后不等待回應(yīng),而是繼續(xù)下一個(gè)目標(biāo)
3、具體實(shí)現(xiàn)
1.獲取IP段
// IP段 '1', '2020-11-26 17:11:39.515', '2020-11-26 17:11:39.515', '1.0.1.0', '1.0.3.255', '福建', '電信' '2', '2020-11-26 17:11:43.553', '2020-11-26 17:11:43.553', '1.0.8.0', '1.0.15.255', '廣東', '電信' '3', '2020-11-26 17:11:47.563', '2020-11-26 17:11:47.563', '1.0.32.0', '1.0.63.255', '廣東', '電信' '4', '2020-11-26 17:11:53.621', '2020-11-26 17:11:53.621', '1.1.0.0', '1.1.0.255', '福建', '電信' '5', '2020-11-26 17:11:57.635', '2020-11-26 17:11:57.635', '1.1.2.0', '1.1.7.255', '福建', '電信' '6', '2020-11-26 17:11:59.642', '2020-11-26 17:11:59.642', '1.1.8.0', '1.1.63.255', '廣東', '電信' '7', '2020-11-26 17:12:05.671', '2020-11-26 17:12:05.671', '1.2.0.0', '1.2.1.255', '福建', '電信' '8', '2020-11-26 17:12:07.674', '2020-11-26 17:12:07.674', '1.2.2.0', '1.2.2.255', '北京', '聯(lián)通' '9', '2020-11-26 17:12:13.690', '2020-11-26 17:12:13.690', '1.2.5.0', '1.2.7.255', '北京', '電信'
2.ping方法(單個(gè),多個(gè)已給出)
// 單個(gè)ping
// IsAlivePing : 檢測(cè)目標(biāo)IP是否能夠ping通,target為目標(biāo)IP
func IsAlivePing(target string) (bool, error) {
pinger, err := ping.NewPinger(target)
if err != nil {
return false, err
}
pinger.Count = 10
PINGTIME := time.Duration(1000)
pinger.Timeout = time.Duration(PINGTIME * time.Millisecond)
pinger.SetPrivileged(true) // 選擇icmp,不選擇udp
pinger.Run()
stats := pinger.Statistics()
// 判斷是否有接收到的包
if stats.PacketsRecv >= 1 {
return true, nil
}
return false, nil
}
// 多個(gè)ping:得到死IP
// FilterActiveIPs : 過(guò)濾活I(lǐng)P,篩選出死IP
func FilterActiveIPs(ips []string) (inactiveIPs []string) {
var lock sync.Mutex
var wg sync.WaitGroup
wg.Add(len(ips))
for _, ip := range ips {
go func(ip string) {
defer wg.Done()
// 判斷是死ip,并且格式正確
isAlive, err := IsAlivePing(ip)
if !isAlive && err == nil {
RandomSleep(2) // 睡眠[1,2]秒,二次確認(rèn)是否為死IP
if isAlive, _ := IsAlivePing(ip); !isAlive {
RandomSleep(2) // 再睡眠[1,2]秒,三次確認(rèn)是否為死IP
if isAlive, _ := IsAlivePing(ip); !isAlive {
lock.Lock()
defer lock.Unlock()
inactiveIPs = append(inactiveIPs, ip)
}
}
}
}(ip)
}
wg.Wait()
return inactiveIPs
}
// 多個(gè)ping:得到活I(lǐng)P
// FilterInactiveIPs : 過(guò)濾死IP,篩選出活I(lǐng)P
func FilterInactiveIPs(ips []string) (activeIPs []string) {
var lock sync.Mutex
var wg sync.WaitGroup
wg.Add(len(ips))
for _, ip := range ips {
go func(ip string) {
defer wg.Done()
// 判斷是活ip,并且格式正確
if isAlive, err := IsAlivePing(ip); isAlive && err == nil {
lock.Lock()
defer lock.Unlock()
activeIPs = append(activeIPs, ip)
}
}(ip)
}
wg.Wait()
return activeIPs
}
// RandomSleep : 隨機(jī)睡眠[1,t]秒
func RandomSleep(t int) {
rand.Seed(time.Now().UnixNano())
r := time.Duration(rand.Intn(t) + 1)
time.Sleep(r * time.Second)
}
3.分解IP段
// Separation : 分解IP段
func (i *impl) Separation(minIP, maxIP string) []string {
shouldStrs := make([]string, 0) // 這是IP段的所有IP
// for i := 0; i < l; i = i + 2 {
min, _ := IPString2Long(minIP) // 這里有一個(gè)轉(zhuǎn)化,我默認(rèn)給的是正確的IP,如果兄弟們不確定傳入的IP格式是否正確,那么要判斷err
max, _ := IPString2Long(maxIP)
for min <= max {
minIPstr, _ := Long2IPString(min)
xxxip := net.ParseIP(minIPstr).To4()
if xxxip[3] != 0 && xxxip[3] != 255 { // 兄弟們,這個(gè)判斷取決于你們想不想要兩個(gè)端點(diǎn)
shouldStrs = append(shouldStrs, minIPstr)
}
min++
}
// TODO: 兄弟們,可以把這句刪除了
fmt.Printf("IP段%s--%s不包括兩端的長(zhǎng)度: %d\n", minIP, maxIP, len(shouldStrs))
return shouldStrs
}
// Long2IPString 把數(shù)值轉(zhuǎn)為ip字符串
func Long2IPString(i uint) (string, error) {
if i > math.MaxUint32 {
return "", errors.New("beyond the scope of ipv4")
}
ip := make(net.IP, net.IPv4len)
ip[0] = byte(i >> 24)
ip[1] = byte(i >> 16)
ip[2] = byte(i >> 8)
ip[3] = byte(i)
return ip.String(), nil
}
// IPString2Long 把ip字符串轉(zhuǎn)為數(shù)值
func IPString2Long(ip string) (uint, error) {
b := net.ParseIP(ip).To4()
if b == nil {
return 0, errors.New("invalid ipv4 format")
}
return uint(b[3]) | uint(b[2])<<8 | uint(b[1])<<16 | uint(b[0])<<24, nil
}
到此這篇關(guān)于go實(shí)現(xiàn)fping功能的文章就介紹到這了,更多相關(guān)go實(shí)現(xiàn)fping內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang中g(shù)in框架接入jwt使用token驗(yàn)證身份
本文主要介紹了golang中g(shù)in框架接入jwt使用token驗(yàn)證身份,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
Go中defer使用場(chǎng)景及注意事項(xiàng)
defer 會(huì)在當(dāng)前函數(shù)返回前執(zhí)行傳入的函數(shù),它會(huì)經(jīng)常被用于關(guān)閉文件描述符、關(guān)閉數(shù)據(jù)庫(kù)連接以及解鎖資源。這篇文章主要介紹了Go中defer使用注意事項(xiàng),需要的朋友可以參考下2021-12-12
Go?interface?接口的最佳實(shí)踐經(jīng)驗(yàn)分享
go?的接口在go的編程里面用的十分頻繁,尤其是空接口的使用,因?yàn)橛辛私涌?,才使得Go語(yǔ)言變得異常的強(qiáng)大,今天給大家介紹下Go?interface?接口的最佳實(shí)踐經(jīng)驗(yàn)分享,感興趣的朋友一起看看吧2022-04-04

