问题描述

我试着用sync.WaitGroup限制协程数量,来写一个端口扫描器,但当协程数量过多的时候,扫描出的结果达不到预期。

如:

设置1000协程,可以扫出80,443,8000,3389
然而设置2000协程后,只能扫出80,443

问题出现的环境背景及自己尝试过哪些方法

在StackOverflow上问过这个问题,英文的回答不是很明白…

这是原回答

You do not wait for the two “non-worker” goroutines in main, so as soon as wg.Wait() there returns, the process shuts down, tearing down any outstanding goroutines.

Since one of them is processing the results, this appears to you as if not all the tasks were processed (and this is true).

以及另一个回答直接给出了优化后的代码:https://play.golang.org/p/_ZD…,在Windows下可行,Linux下一样不行。

相关代码

package main
import (
"fmt"
"net"
"sync"
"time"
)
type Job struct {
host string
port int
}
type Result struct {
job    Job
status bool
}
var jobs = make(chan Job)
var results = make(chan Result)
func worker(wg *sync.WaitGroup) {
for job := range jobs {
_, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", job.host, job.port), time.Millisecond*1500)
if err != nil {
results <- Result{job, false}
} else {
results <- Result{job, true}
}
}
wg.Done()
}
const host = "127.0.0.1"
func main() {
wg := sync.WaitGroup{}
go func() {
for i := 1; i < 65535; i++ {
jobs <- Job{host, i}
}
close(jobs)
}()
go func() {
for result := range results {
if result.status {
fmt.Println(result.job, "open")
}
}
}()
for i := 1; i < 4500; i++ {
wg.Add(1)
go worker(&wg)
}
wg.Wait()
}

你期待的结果是什么?实际看到的错误信息又是什么?

我希望无论是Win还是Linux都能够获取到所有的端口开放情况。

在Windows中由于扫描速度不快,可以扫描出全部端口

{127.0.0.1 135} open
{127.0.0.1 443} open
{127.0.0.1 445} open
{127.0.0.1 808} open
{127.0.0.1 902} open
{127.0.0.1 912} open

Linux下,就达不到预期了

ubuntu@pc:~/Desktop$ go run port.go
{127.0.0.1 80} open
{127.0.0.1 631} open
{127.0.0.1 3306} open

回答

是不是有可能因为链接过多 Linux自动丢弃了部分tcp请求 可以考虑非超时错误重试一次

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Scroll Up