我目前正在学习去的过程。要做到这一点,我正在制作一个相对简单的portscanner。在goroutines扫描端口
我面临的问题是扫描这些端口需要相当长的时间。我的行为是,如果我扫描端口(定义为int32的数组(protobuf doesnt支持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"`
}
如在代码snipp的第一行看到et,我已经定义了一个分片,以保存所有结果,我的想法是我的应用程序并行扫描端口,并在完成后将结果发送给感兴趣的任何人。
但是,使用此代码,程序卡住了。
我跑这个基准来测试其性能:
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)
}
}
的原因是什么它卡住。看看这段代码是否给了我们什么东西?因此,在短期
,我想我的最终结果是为每个端口在不同的走常规扫描,当他们全部结束,一切都一起在一个产生ScanResult的切片。
我希望我已经清楚,并为您提供足够的信息来帮助我。
哦,IM尤其是寻找指针,学习一下,不persee工作代码示例。
你的先生,是个英雄!我根本不知道你需要关闭频道。现在有道理。感谢您的解释。端口扫描的性能现在好多了。 –