Go 同时扫描多个端口时结果不可靠

Go 同时扫描多个端口时结果不可靠,go,networking,tcp,port-scanning,Go,Networking,Tcp,Port Scanning,背景: 我正在阅读Black Hat Go,作者介绍了一个使用Go例程的简单端口扫描仪: 主程序包 进口( “fmt” “净额” ) func main(){ 对于i:=1;i您的主函数将在for循环完成后立即退出。如果主函数退出,则它启动的所有goroutine也将退出。您需要等待goroutine完成。例如,可以通过以下方式实现 主程序包 进口( “fmt” “净额” “同步” “时间” ) func main(){ //这将帮助您跟踪goroutines var wg sync.WaitG

背景

我正在阅读Black Hat Go,作者介绍了一个使用Go例程的简单端口扫描仪:

主程序包
进口(
“fmt”
“净额”
)
func main(){

对于i:=1;i您的主函数将在for循环完成后立即退出。如果主函数退出,则它启动的所有goroutine也将退出。您需要等待goroutine完成。例如,可以通过以下方式实现

主程序包
进口(
“fmt”
“净额”
“同步”
“时间”
)
func main(){
//这将帮助您跟踪goroutines
var wg sync.WaitGroup

对于i:=1;我运行了上面的代码,当我扫描1到9000个端口时,它仍然无法正确检测打开的端口。如果我将其缩小到较小的范围,它似乎可以工作。使用调试器运行它或记录错误:由于TCP连接通常需要打开两个文件描述符,因此很可能会用完可用的文件描述符。我是wo正在研究一个将相应分块的解决方案。能否添加代码以打印
err
,并在问题中添加一些输出示例?一个限制可能是每个进程允许有多少个打开的文件描述符。@MarkPlotnick你是对的!我遇到了
套接字:打开的文件太多
错误。是否可以编写他的回答让我能接受吗?
package main

import (
    "fmt"
    "net"
)

func main() {
    for i := 1; i <= 9000; i++ {
        go func(j int) {
            address := fmt.Sprintf("127.0.0.1:%d", j)
            conn, err := net.Dial("tcp", address)
            if err != nil {
                return
            }
            conn.Close()
            fmt.Printf("%d open\n", j)
        }(i)
    }
}