Golang定期检查端口上的TCP连接

时间:2016-12-21 09:25:31

标签: go

我正在尝试编写一个小的golang程序,它会定期执行lsof -i:<port>来检查端口上打开的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},

有人能让我知道出了什么问题吗?

  • Go Version - 1.7.3

1 个答案:

答案 0 :(得分:3)

问题不在Ticker 试试

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

您不得按价值传递WaitGroup。将wg作为指针传递将解决问题。功能正在等待

将其更新为

    .....
    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) {
   .......

以下是游戏link