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

标签 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 版本 - 1.7.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

关于Golang 定期检查端口上打开的 TCP 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41259191/

相关文章:

docker - 来自 Docker 的 Golang 编译缓存

在 go 程序中运行时 Bash 脚本挂起

go - 在 IntelliJ 中保存文件时执行 gofmt

go - 重写goroutine函数并进行恢复

go - 使用 Golang net.Conn.Read 读取整个数据

http - Go http客户端不遵循重定向

opencv - go 的计算机视觉在我尝试下载它时出现错误

go - 如何将图像的 int64 大小作为字符串获取?

reflection - 在不使用反射的情况下检查 Go 中的接口(interface)值是否为 nil

go - 如何使用索引构造翻转的单个位位域?