Created
September 11, 2020 10:37
-
-
Save woodsaj/310ffafb1abde66b9373347d3eb12db9 to your computer and use it in GitHub Desktop.
Example usage of github.com/woodsaj/go-pinger
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"net" | |
"os" | |
"os/signal" | |
"strings" | |
"sync" | |
"time" | |
pinger "github.com/raintank/go-pinger" | |
) | |
type resultSet struct { | |
Host string | |
Success bool | |
} | |
func main() { | |
// initialize and start our pinger service that | |
// handles executing pings. | |
p, err := pinger.NewPinger("ipv4", 1000) | |
if err != nil { | |
log.Fatal(err) | |
} | |
p.Start() | |
// use channel to signal when all of our pings are complete | |
done := make(chan struct{}) | |
// run our pings | |
go pinghosts(p, done) | |
// wait for our pings to be done or an interrupt to be received | |
waitforinterrupt(done) | |
fmt.Printf("\n") | |
} | |
func pinghosts(p *pinger.Pinger, done chan struct{}) { | |
defer close(done) | |
results := make(chan resultSet, 100) | |
host := "google.at" | |
var wg sync.WaitGroup | |
for i := 0; i < 5; i++ { | |
wg.Add(1) | |
go func(host string) { | |
defer wg.Done() | |
r, err := ping(p, host) | |
if err != nil { | |
fmt.Printf("no results") | |
return | |
} | |
results <- r | |
}(host) | |
} | |
// wait for all spawned goroutines to finish, then close our | |
// results channel so we know not to expect any more results. | |
go func() { | |
wg.Wait() | |
close(results) | |
}() | |
i := 0 | |
for v := range results { | |
fmt.Printf("%d - %+v\n", i, v) | |
i++ | |
} | |
} | |
func ping(p *pinger.Pinger, host string) (resultSet, error) { | |
addr, err := resolveHost(host, "v4") | |
if err != nil { | |
log.Println(err) | |
return resultSet{}, err | |
} | |
stats, err := p.Ping(net.ParseIP(addr), 2, time.Second*2) | |
if err != nil { | |
log.Println(err) | |
return resultSet{}, err | |
} | |
res := resultSet{Host: host} | |
if stats.Sent != stats.Received { | |
res.Success = false | |
fmt.Printf("%s Sent: %d\n", host, stats.Sent) | |
fmt.Printf("%s Received: %d\n", host, stats.Received) | |
} else { | |
res.Success = true | |
} | |
return res, nil | |
} | |
func waitforinterrupt(done chan struct{}) { | |
var endwaiter sync.WaitGroup | |
endwaiter.Add(1) | |
var signalchannel chan os.Signal | |
signalchannel = make(chan os.Signal, 1) | |
signal.Notify(signalchannel, os.Interrupt) | |
go func() { | |
// wait for either an interrupt or "done" signal | |
select { | |
case <-signalchannel: | |
case <-done: | |
} | |
endwaiter.Done() | |
}() | |
endwaiter.Wait() | |
} | |
func resolveHost(host, ipversion string) (string, error) { | |
addrs, err := net.LookupHost(host) | |
if err != nil || len(addrs) < 1 { | |
return "", fmt.Errorf("failed to resolve hostname to IP") | |
} | |
for _, addr := range addrs { | |
if ipversion == "any" { | |
return addr, nil | |
} | |
if strings.Contains(addr, ":") || strings.Contains(addr, "%") { | |
if ipversion == "v6" { | |
return addr, nil | |
} | |
} else { | |
if ipversion == "v4" { | |
return addr, nil | |
} | |
} | |
} | |
return "", fmt.Errorf("failed to resolve hostname to valid IP") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment