问题描述
我想要通过协程扫描目标主机范围内的开放端口,比如扫描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
同时,通道容量不用设置那么大,处理好写入和读出的逻辑,很小的容量也可以运行下去,不堵塞就好