]> Sergey Matveev's repositories - btrtrc.git/commitdiff
cmd/dht-ping: Various improvements more like a real ping program
authorMatt Joiner <anacrolix@gmail.com>
Tue, 18 Nov 2014 18:36:36 +0000 (12:36 -0600)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 18 Nov 2014 18:36:36 +0000 (12:36 -0600)
cmd/dht-ping/main.go

index b5cf5236ee925a4d44d934fa4c5dabf44861c9b9..80cd2cc103d922350df326e55e4672728cb40045 100644 (file)
@@ -2,9 +2,11 @@ package main
 
 import (
        "flag"
+       "fmt"
        "log"
        "net"
        "os"
+       "time"
 
        "bitbucket.org/anacrolix/go.torrent/dht"
 )
@@ -12,10 +14,12 @@ import (
 type pingResponse struct {
        addr string
        krpc dht.Msg
+       rtt  time.Duration
 }
 
 func main() {
        log.SetFlags(log.LstdFlags | log.Lshortfile)
+       timeout := flag.Duration("timeout", -1, "maximum timeout")
        flag.Parse()
        pingStrAddrs := flag.Args()
        if len(pingStrAddrs) == 0 {
@@ -28,23 +32,49 @@ func main() {
        }
        log.Printf("dht server on %s", s.LocalAddr())
        pingResponses := make(chan pingResponse)
-       for _, netloc := range pingStrAddrs {
-               addr, err := net.ResolveUDPAddr("udp4", netloc)
-               if err != nil {
-                       log.Fatal(err)
+       timeoutChan := make(chan struct{})
+       go func() {
+               for i, netloc := range pingStrAddrs {
+                       if i != 0 {
+                               time.Sleep(1 * time.Millisecond)
+                       }
+                       addr, err := net.ResolveUDPAddr("udp4", netloc)
+                       if err != nil {
+                               log.Fatal(err)
+                       }
+                       t, err := s.Ping(addr)
+                       if err != nil {
+                               log.Fatal(err)
+                       }
+                       start := time.Now()
+                       go func(addr string) {
+                               resp := <-t.Response
+                               pingResponses <- pingResponse{
+                                       addr: addr,
+                                       krpc: resp,
+                                       rtt:  time.Now().Sub(start),
+                               }
+                       }(netloc)
                }
-               t, err := s.Ping(addr)
-               if err != nil {
-                       log.Fatal(err)
+               if *timeout >= 0 {
+                       time.Sleep(*timeout)
+                       close(timeoutChan)
                }
-               go func(addr string) {
-                       pingResponses <- pingResponse{
-                               addr: addr,
-                               krpc: <-t.Response,
-                       }
-               }(netloc)
-       }
+       }()
+       responses := 0
+pingResponses:
        for _ = range pingStrAddrs {
-               log.Printf("%q", <-pingResponses)
+               select {
+               case resp := <-pingResponses:
+                       if resp.krpc == nil {
+                               break
+                       }
+                       responses++
+                       fmt.Printf("%-65s %s\n", fmt.Sprintf("%x (%s):", resp.krpc["r"].(map[string]interface{})["id"].(string), resp.addr), resp.rtt)
+               case <-timeoutChan:
+                       break pingResponses
+               }
        }
+       // timeouts := len(pingStrAddrs) - responses
+       fmt.Printf("%d/%d responses (%f%%)\n", responses, len(pingStrAddrs), 100*float64(responses)/float64(len(pingStrAddrs)))
 }