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")
}
}
这样,一个简单的扫描器就完成了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具