2016-12-21 4 views
0

私は定期的にlsof -i:<port>を実行してポートで開いているTCP接続の数を確認する小さなゴランプログラムを作成しようとしています。コードは以下のようになります: -定期的にGolangがポートで開いているTCP接続を確認しています

package main 

import (
    "fmt" 
    "log" 
    "os/exec" 
    "strings" 
    "sync" 
    "time" 
) 

type Lsof struct { 
    Command string 
    Pid  string 
    User  string 
    Fd  string 
    Type  string 
    Device string 
    SizeOff string 
    Node  string 
    Name  string 
    TCPState string 
} 

//var result = make([]*Lsof, 0) 
var ports = []int{30001, 30002} 

func main() { 
    done := make(chan bool) 
    ticker := time.NewTicker(5 * time.Millisecond) 
    go func() { 
     for t := range ticker.C { 
      fmt.Println("Tick at", t) 
      connectionsCount() 
     } 
    }() 
    <-done 
} 

func connectionsCount() { 
    var wg sync.WaitGroup 
    wg.Add(len(ports)) 
    for _, v := range ports { 
     go count(v, wg) 
    } 
    wg.Wait() 
} 

func count(port int, wg sync.WaitGroup) { 
    defer wg.Done() 
    var tcpState = make(map[string]int) 
    out, err := exec.Command("/bin/sh", "-c", fmt.Sprintf("lsof -i:%d", port)).Output() 
    if err != nil { 
     log.Fatal(err) 
    } 
    //fmt.Println(string(out)) 
    num := strings.Split(string(out), "\n") 
    for no, n := range num { 
     if no == 0 { 
      continue 
     } 
     n = strings.TrimSpace(n) 
     if len(n) <= 0 { 
      continue 
     } 
     i := 0 
     temp := strings.Split(n, " ") 
     cleanedVal := make([]string, 10) 
     for _, v := range temp { 
      v = strings.TrimSpace(v) 
      if len(v) <= 0 { 
       continue 
      } 
      cleanedVal[i] = v 
      i++ 
     } 
     if len(cleanedVal) < 8 { 
      //log.Println(n) 
      continue 
     } 
     l := new(Lsof) 
     l.Command = cleanedVal[0] 
     l.Pid = cleanedVal[1] 
     l.User = cleanedVal[2] 
     l.Fd = cleanedVal[3] 
     l.Type = cleanedVal[4] 
     l.Device = cleanedVal[5] 
     l.SizeOff = cleanedVal[6] 
     l.Node = cleanedVal[7] 
     l.Name = cleanedVal[8] 
     if l.Node == "TCP" { 
      l.TCPState = cleanedVal[9] 
      count, ok := tcpState[l.TCPState] 
      if !ok { 
       tcpState[l.TCPState] = 1 
      } else { 
       tcpState[l.TCPState] = count + 1 
      } 
     } 
     //fmt.Printf("\n%+v", *l) 
     //result = append(result, l) 
    } 
    fmt.Printf("Port=%d ", port) 
    for k, v := range tcpState { 
     fmt.Printf("{TCP State=%s,Value=%d},", k, v) 
    } 
    fmt.Println() 
} 

しかし、プログラムを実行すると、ティッカーが定期的にチェックされていません。

Tick at 2016-12-21 14:37:03.847694697 +0530 IST 
Port=30002 {TCP State=(LISTEN),Value=2}, 
Port=30001 {TCP State=(LISTEN),Value=2}, 

誰かが間違っていることを教えてもらえますか?

  • ゴーバージョン - 1.7.3

答えて

2

ここで問題がTicker ではなく、あなたが値によってWaitGroupを渡してはならない

for t := range ticker.C { 
     fmt.Println("Tick at", t) 
     // connectionsCount() 
    } 

を試してみてください。ポインタとしてwgを渡すと問題が解決します。 fuctionはここ

..... 
    func connectionsCount() { 
     var wg = &sync.WaitGroup{} 
     wg.Add(len(ports)) 
     for _, v := range ports { 
      go count(v, wg) 
     } 
     wg.Wait() 
    } 
    func count(port int, wg *sync.WaitGroup) { 
    ....... 

にこれまで

更新のためにそれを待っていたことの答えはあなたをelped場合upvoteしてくださいプレイlink

+0

@tukです –

関連する問題