问答

Golang 协程TCP扫描退出问题

作者:admin 2021-06-23 我要评论

问题描述 我想要通过协程扫描目标主机范围内的开放端口,比如扫描baidu.com的1-1024端口。 但是我写的代码会提前退出,还没有将net.Dial的结果插入retChan管道就...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

问题描述

我想要通过协程扫描目标主机范围内的开放端口,比如扫描baidu.com的1-1024端口。

但是我写的代码会提前退出,还没有将net.Dial的结果插入retChan管道就已经退出主协程了。

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

在看了很多协程池之类的方法后还是失败...

相关代码

package main

import (
    "fmt"
    "net"
    "time"
)

func scanPort(jobChan <-chan int, retChan chan<- string) {
    // 从管道取端口
    for port := range jobChan {

        // 发起tcp连接
        target := fmt.Sprintf("149.129.68.235:%d", port)

        _, err := net.Dial("tcp", target)

        // 未发生错误时写入结果管道
        if err == nil {
            retChan <- fmt.Sprintf("%s is open", target)
        }

    }
}

func main() {
    jobChan := make(chan int, 65535)
    retChan := make(chan string, 65535)

    // 写入1024个待扫描端口到任务管道
    go func() {
        for i := 0; i < 1024; i++ {
            jobChan <- i
        }
    }()

    // 创建n个协程
    for i := 0; i < 10; i++ {
        go scanPort(jobChan, retChan)
    }

    // 关闭
    time.Sleep(time.Second)
    close(retChan)

    // 打印结果
    for ret := range retChan {
        fmt.Println(ret)
    }

}

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

能够正常扫描到已开放的端口

###

你的代码如何保证 close时, 你的协程已经处理完所有的逻辑呢,你主进程休眠的1秒,未必够啊
正确的做法,使用 sync.WaitGroup

同时,通道容量不用设置那么大,处理好写入和读出的逻辑,很小的容量也可以运行下去,不堵塞就好

package main

import (
    "fmt"
    "net"
    "sync"
    "time"
)

func scanPort(jobChan <-chan int, retChan chan<- string, wg *sync.WaitGroup) {
    defer wg.Done()
    // 从管道取端口
    for port := range jobChan {
        // 发起tcp连接
        target := fmt.Sprintf("149.129.68.235:%d", port)
        //fmt.Println(target)
        _, err := net.DialTimeout("tcp", target, 100*time.Millisecond)
        //_, err := net.Dial("tcp", target)
        // 未发生错误时写入结果管道
        if err == nil {
            retChan <- fmt.Sprintf("%s is open", target)
        }

    }
}

func main() {
    jobChan := make(chan int, 5)
    retChan := make(chan string, 5)

    // 写入1024个待扫描端口到任务管道
    go func() {
        for i := 0; i < 1024; i++ {
            jobChan <- i
        }
        close(jobChan)
    }()
    wg := sync.WaitGroup{}
    // 创建n个协程
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go scanPort(jobChan, retChan, &wg)
    }
    go func() {
        for ret := range retChan {
            fmt.Println(ret)
        }
    }()
    // 关闭
    wg.Wait()
    close(retChan)
}

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • Golang 协程TCP扫描退出问题

    Golang 协程TCP扫描退出问题

  • java web问题?

    java web问题?

  • vue中使用mqtt IE(11,edge,10等) 报语

    vue中使用mqtt IE(11,edge,10等) 报语

  • h5 页面创建订单+JSAPI唤起收银台支付

    h5 页面创建订单+JSAPI唤起收银台支付

腾讯云代理商
海外云服务器