TCP连接函数
定义一个connect函数进行TCP连接,接收三个参数:
- ports chan int:端口管道,用于接收要扫描的端口
- results chan int:结果管道,用于发送结果
- host string:主机,用于拼接地址
从端口管道中读取端口后与主机拼接成完整地址,使用net.Dial测试TCP连接是否成功,并将结果发送到results管道,失败则返回0,成功则返回端口。
代码语言:javascript复制func connect(ports chan int, results chan int, host string) {
// 从管道接收要扫描的端口
for p := range ports {
// 拼接地址
address := fmt.Sprintf("%s:%d", host, p)
// TCP连接
conn, err := net.Dial("tcp", address)
if err != nil {
results <- 0
continue
}
// 关闭连接
conn.Close()
// 将结果发送到管道
results <- p
}
}
封装函数
定义一个run函数,接收四个参数:
- start int:起始端口
- end int:结束端口
- rlen int:goroutine池缓存大小
- host string:主机
该函数用于创建管道和goroutine池,并向管道发送要扫描的端口范围,最后从管道中接收结果,经过排序后返回一个切片。
代码语言:javascript复制func run(start int, end int, rlen int, host string) []int {
// 创建管道
ports := make(chan int, rlen)
results := make(chan int)
// 切片,用于保存扫描的结果
var openports []int
// goroutine池,并发执行TCP连接函数
for i := 0; i < cap(ports); i {
go connect(ports, results, host)
}
// 向管道发送要扫描的端口
go func() {
for i := start; i <= end; i {
ports <- i
}
}()
// 从管道接收结果
for i := start; i <= end; i {
port := <-results
if port != 0 {
openports = append(openports, port)
}
}
// 关闭管道
close(ports)
close(results)
// 排序
sort.Ints(openports)
// 返回数据
return openports
}
主函数
调用封装函数,向封装函数传递参数,并输出结果 func main() {
代码语言:javascript复制 // 参数
host := "127.0.0.1"
start := 0
end := 66535
rlen := 4096
// 调用封装函数,接收返回值
res := run(start, end, rlen, host)
// 输出结果
for _, port := range res {
fmt.Printf("%d is openn", port)
}
}
完整代码
scan.go
代码语言:javascript复制package main
import (
"fmt"
"net"
"sort"
)
func connect(ports chan int, results chan int, host string) {
// 从管道接收要扫描的端口
for p := range ports {
// 拼接地址
address := fmt.Sprintf("%s:%d", host, p)
// TCP连接
conn, err := net.Dial("tcp", address)
if err != nil {
results <- 0
continue
}
// 关闭连接
conn.Close()
// 将结果发送到管道
results <- p
}
}
func run(start int, end int, rlen int, host string) []int {
// 创建管道
ports := make(chan int, rlen)
results := make(chan int)
// 切片,用于保存扫描的结果
var openports []int
// goroutine池,并发执行TCP连接函数
for i := 0; i < cap(ports); i {
go connect(ports, results, host)
}
// 向管道发送要扫描的端口
go func() {
for i := start; i <= end; i {
ports <- i
}
}()
// 从管道接收结果
for i := start; i <= end; i {
port := <-results
if port != 0 {
openports = append(openports, port)
}
}
// 关闭管道
close(ports)
close(results)
// 排序
sort.Ints(openports)
// 返回数据
return openports
}
func main() {
// 参数
host := "127.0.0.1"
start := 0
end := 66535
rlen := 4096
// 调用封装函数,接收返回值
res := run(start, end, rlen, host)
// 输出结果
for _, port := range res {
fmt.Printf("%d is openn", port)
}
}