0
点赞
收藏
分享

微信扫一扫

go语言学习-实现并发TCP扫描器

一叶随风_c94d 2023-03-09 阅读 86

最近在学习go语言,跟着练手了一个项目,做一个TCP扫描器。

要求

  • 使用TCP连接,指定主机的IP,扫描端口范围
  • 能够自定义解析命令参数
  • 并发执行,多线程,加快扫描速度
  • 线程之间互拆锁,不会相会影响

实现的代码如下

package main
//TcpScanner.go
import (
"flag"
"fmt"
"net"
"sync"
"time"
)
//定义扫描函数,参数分别是主机,端口,和超时时间,返回值true或者false
func IsOpen(host string, port int, timeout time.Duration) bool {
//修庙1毫秒
time.Sleep(time.Millisecond * 1)
//net包,DialTimout函数
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", host, port), timeout)
//连接如果没有报错,关闭连接并返回true
if err == nil {
_ = conn.Close()
return true
}
//否则返回false
return false
}

func main() {
//flag包解命令行参数
hostname := flag.String("hostname", "", "hostname to test")
startPort := flag.Int("start-port", 80, "the port on which the scanning starts")
endPort := flag.Int("end-port", 100, "the port from which the scanning ends")
timeout := flag.Duration("timeout", time.Millisecond*200, "timeout")
flag.Parse()

//初始化端口列表
ports := []int{}
//WaiGroup方法,等待线程结束
wg := &sync.WaitGroup{}
//增加互拆锁
mutex := &sync.Mutex{}
for port := *startPort; port <= *endPort; port++ {
//Add方法来设定应等待的线程的数量。
//每个被等待的线程在结束时应调用Done方法
wg.Add(1)
//开启go并发扫描
go func(p int) {
//调用IsOpen函数
opened := IsOpen(*hostname, p, *timeout)
//如果为真,说明扫描到端口
//进程加锁
//append到端口列表中
if opened {
mutex.Lock() //加锁
ports = append(ports, p)
mutex.Unlock() //解锁
}
wg.Done()//等待结束
}(port) //异步情况,调用实参
}
wg.Wait() //Wait自行解锁并阻塞当前线程,等待循环下次执行
//输出扫描到的端口列表
fmt.Printf("opened ports:%v\n", ports)
}

关于各个标准包/库的用法,可以参考

​​​​​​https://studygolang.com/pkgdoc​​

编写完成后,go buid 编译

#编译
go build TcpScanner.go
#使用帮助
.\TcpScanner.ext -h
TcpScanner.go
Usage of D:\GoProject\src\TCPScaner\TcpScanner.exe:
-end-port int
the port from which the scanning ends (default 100)
-hostname string
hostname to test
-start-port int
the port on which the scanning starts (default 80)
-timeout duration
timeout (default 200ms)

#使用示例
.\TcpScanner.exe -hostname www.baidu.com -start-port 80 -end-port 1443 -timeout 200ms

go语言学习-实现并发TCP扫描器_Parse

go 真的很快

举报

相关推荐

0 条评论