定义一个connect函数进行TCP连接,接收三个参数:
从端口管道中读取端口后与主机拼接成完整地址,使用net.Dial测试TCP连接是否成功,并将结果发送到results管道,失败则返回0,成功则返回端口。
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函数,接收四个参数:
该函数用于创建管道和goroutine池,并向管道发送要扫描的端口范围,最后从管道中接收结果,经过排序后返回一个切片。
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 open\n", port)
}
}
scan.go
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 open\n", port)
}
}