golang创建简单tcp扫描器

实现最简单的tcp扫描器:

最简单的tcp扫描器非常简单,我们只需要知道一个函数 net.Dial()

Go语言中 Dial() 函数用于创建网络连接,函数原型如下:
func Dial(network, address string) (Conn, error) {
var d Dialer
return d.Dial(network, address)
}
参数说明如下:
network 参数表示传入的网络协议(比如 tcp、udp 等);
address 参数表示传入的 IP 地址或域名,而端口号是可选的,如果需要指定的话,以:的形式跟在地址或域名的后面即可。如果连接成功,该函数返回连接对象,否则返回 error。

此函数会返回两个参数,类型分别为conn和err,如果连接成功err会为空,也就是nil。所以我们只需要判断err == nil。就能知道是否可以连接,从而达到探测的作用。下面是实现:

func main() {
	_, err := net.Dial("tcp", "scanme.nmap.org:80")
	if err == nil {
		fmt.Println("连接成功")
	}
}

很明显,如果能够连接,将会返回连接成功。这只是探测nmap测试网站的80端口,作为扫描肯定是不够的,但是以此为基础,我们可以很轻易的想到在代码的外层添加上循环,tcp端口范围为165535,这里我们只探测11000作为例子:

func main() {
	for i := 1; i <= 1000; i++ {
		addstr := fmt.Sprintf("scanme.nmap.org:%d", i)
		conn, err := net.Dial("tcp", addstr)
		if err != nil {
			continue
		}
		conn.Close()
		fmt.Println("端口", i, "开启")
	}
}

这就已经是最简单的扫描器了,当然,这个的扫描速度会慢的离谱,我们需要加上并发,go实现并发非常方便。但是我们要知道并不是并发数越高越好。
在这个扫描过程中,如果并发数量过高,会导致扫描速度过快而导致扫描结果不准确。所以我们需要控制并发,下面是用通道控制并发:

func worker(ports, results chan int) {
	for p := range ports {
		address := fmt.Sprintf("scanme.nmap.org:%d", p)
		conn, err := net.Dial("tcp", address)
		if err != nil {
			results <- 0
			continue
		}
		conn.Close()
		results <- p
	}
}

func main() {
	ports := make(chan int, 100)
	results := make(chan int)
	var resultPortsList []int
	for i := 1; i <= 50; i++ {
		go worker(ports, results)
	}
	go func() {
		for i := 1; i <= 1000; i++ {
			ports <- i
		}
	}()
	for i := 0; i < 1000; i++ {
		port := <-results
		if port != 0 {
			resultPortsList = append(resultPortsList, port)
		}
	}
	close(ports)
	close(results)
	sort.Ints(resultPortsList)
	for _, port := range resultPortsList {
		fmt.Println(port, "is open")
	}
}

这样,一个简单的扫描器就完成了。

posted @   Azathoth_jk  阅读(172)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示