gpt4 book ai didi

go - 在 goroutine 中扫描端口

转载 作者:IT王子 更新时间:2023-10-29 01:54:51 27 4
gpt4 key购买 nike

我目前正在学习围棋。为此,我正在制作一个相对简单的端口扫描器。

我面临的问题是扫描这些端口需要花费大量时间。我的行为是,如果我扫描端口(定义为 int32 数组(protobuf 不支持 int16),则不使用 goroutines 是有效的,但是扫描超过 5 个端口时速度很慢,因为它不是并行运行。

为了实现并行性,我想出了以下代码(解释 + 问题在代码之后):

//entry point for port scanning
var results []*portscan.ScanResult
//len(splitPorts) is the given string (see benchmark below) chopped up in an int32 slice
ch := make(chan *portscan.ScanResult, len(splitPorts))

var wg sync.WaitGroup
for _, port := range splitPorts {
connect(ip, port, req.Timeout, ch, &wg)
}
wg.Wait()

for elem := range ch {
results = append(results, elem)
}

// go routine
func connect(ip string, port, timeout int32, ch chan *portscan.ScanResult, wg *sync.WaitGroup) {
wg.Add(1)
go func() {
res := &portscan.ScanResult{
Port: port,
IsOpen: false,
}
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, port), time.Duration(timeout)*time.Millisecond)

if err == nil {
conn.Close()
res.IsOpen = true
}
ch <- res
wg.Done()
}()
}

所以 protobuf 为我准备了一个结构,如下所示:

type ScanResult struct {
Port int32 `protobuf:"varint,1,opt,name=port" json:"port,omitempty"`
IsOpen bool `protobuf:"varint,2,opt,name=isOpen" json:"isOpen,omitempty"`
}

如代码片段的第一行所示,我定义了一个 slice 来保存所有结果,我的想法是我的应用程序并行扫描端口,完成后将结果发送给任何感兴趣的人。

但是,使用这段代码,程序会卡住。

我运行这个基准测试来测试它的性能:

func BenchmarkPortScan(b *testing.B) {
request := &portscan.ScanPortsRequest{
Ip: "62.129.139.214",
PortRange: "20,21,22,23",
Timeout: 500,
}

svc := newService()

for i := 0; i < b.N; i++ {
svc.ScanPorts(nil, request)
}
}

卡住是什么原因。看看这段代码会泄露什么吗?

所以简而言之,我希望我的最终结果是在不同的 go 例程中扫描每个端口,当它们全部完成时,所有内容都汇集在一个 ScanResult 的结果片段中。

我希望我已经说清楚并提供了足够的信息让你们帮助我。

哦,我特别在寻找指针和学习点,而不是查看工作代码示例。

最佳答案

您需要在 wg.Wait() 之后关闭 channel 。否则你的 range for 循环会卡住。

除此之外,您的代码看起来还不错。

关于go - 在 goroutine 中扫描端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38422600/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com