Go 语言编写 TCP 扫描器TCP

  • TCP,也就是传输控制协议(Transmission Control Protocol)。

TCP握手

  • 建立 TCP连接(或者叫打开端口),需要3次握手

客户端 -> 端口打开 ->服务器

  1. syn (请求建立新连接)
  2. syn-ack (同意创建新连接)
  3. ack (表示响应)
  • 服务端端口关闭 Closed Port
    • client -syn-> Server
    • Server -rst-> Client
  • 如果存在防火墙 Filtered Port
    • Client —syn (Timeout)— Firewall Server

非并发的 TCP 扫描器

创建目录并在该目录创建main.go 文件

~/Code/go via ? v1.20.3 via ? base➜ mcd tcp-scannerCode/go/tcp-scanner via ? v1.20.3 via ? base➜ go mod initgo: cannot determine module path for source directory /Users/qiaopengjun/Code/go/tcp-scanner (outside GOPATH, module path must be specified)Example usage:'go mod init example.com/m' to initialize a v0 or v1 module'go mod init example.com/m/v2' to initialize a v2 moduleRun 'go help mod init' for more information.Code/go/tcp-scanner via ? v1.20.3 via ? base➜ go mod init tcp-scannergo: creating new go.mod: module tcp-scannerCode/go/tcp-scanner via ? v1.20.3 via ? base➜ cCode/go/tcp-scanner via ? v1.20.3 via ? base➜

main.go 文件

package mainimport ("fmt""net")func main() {for i := 21; i < 120; i++ {address := fmt.Sprintf("20.194.168.28:%d", i)conn, err := net.Dial("tcp", address)if err != nil {fmt.Printf("%s failed 关闭了\n", address)continue}conn.Close()fmt.Printf("%s connected 打开了!!!\n", address)}}

并发的 TCP 扫描器

package mainimport ("fmt""net""sync""time")func main() {start := time.Now()var wg sync.WaitGroupfor i := 21; i < 120; i++ {wg.Add(1)go func(j int) {defer wg.Done()address := fmt.Sprintf("20.194.168.28:%d", j)conn, err := net.Dial("tcp", address)if err != nil {fmt.Printf("%s 关闭了\n", address)return}conn.Close()fmt.Printf("%s 打开了!!!\n", address)}(i)}wg.Wait()elapsed := time.Since(start) / 1e9fmt.Printf("\n\n%d seconds", elapsed)}// func main() {// for i := 21; i < 120; i++ {// address := fmt.Sprintf("20.194.168.28:%d", i)// conn, err := net.Dial("tcp", address)// if err != nil {// fmt.Printf("%s failed 关闭了\n", address)// continue// }// conn.Close()// fmt.Printf("%s connected 打开了!!!\n", address)// }// }

并发的 TCP 扫描器 – WORKER 池

package mainimport ("fmt""sync")func worker(ports chan int, wg *sync.WaitGroup) {for p := range ports {fmt.Println("p", p)wg.Done()}}func main() {ports := make(chan int, 100)var wg sync.WaitGroupfor i := 0; i < cap(ports); i++ {go worker(ports, &wg)}for i := 1; i < 1024; i++ {wg.Add(1)ports <- i}wg.Wait()close(ports)}// func main() {// start := time.Now()// var wg sync.WaitGroup// for i := 21; i < 120; i++ {// wg.Add(1)// go func(j int) {// defer wg.Done()// address := fmt.Sprintf("20.194.168.28:%d", j)// conn, err := net.Dial("tcp", address)// if err != nil {// fmt.Printf("%s 关闭了\n", address)// return// }// conn.Close()// fmt.Printf("%s 打开了!!!\n", address)// }(i)// }// wg.Wait()// elapsed := time.Since(start) / 1e9// fmt.Printf("\n\n%d seconds", elapsed)// }// func main() {// for i := 21; i < 120; i++ {// address := fmt.Sprintf("20.194.168.28:%d", i)// conn, err := net.Dial("tcp", address)// if err != nil {// fmt.Printf("%s failed 关闭了\n", address)// continue// }// conn.Close()// fmt.Printf("%s connected 打开了!!!\n", address)// }// }

优化之后

package mainimport ("fmt""net""sort")func worker(ports chan int, results chan int) {for p := range ports {address := fmt.Sprintf("20.194.168.28:%d", p)conn, err := net.Dial("tcp", address)if err != nil {results <- 0continue}conn.Close()results <- p}}func main() {ports := make(chan int, 100)results := make(chan int)var openports []intvar closeports []intfor i := 0; i < cap(ports); i++ {go worker(ports, results)}go func() {for i := 1; i < 1024; i++ {ports <- i}}()for i := 1; i < 1024; i++ {port := <-resultsif port != 0 {openports = append(openports, port)} else {closeports = append(closeports, port)}}close(ports)close(results)sort.Ints(openports)sort.Ints(closeports)for _, port := range closeports {fmt.Printf("%d closed\n", port)}for _, port := range openports {fmt.Printf("%d opened\n", port)}}// func main() {// start := time.Now()// var wg sync.WaitGroup// for i := 21; i < 120; i++ {// wg.Add(1)// go func(j int) {// defer wg.Done()// address := fmt.Sprintf("20.194.168.28:%d", j)// conn, err := net.Dial("tcp", address)// if err != nil {// fmt.Printf("%s 关闭了\n", address)// return// }// conn.Close()// fmt.Printf("%s 打开了!!!\n", address)// }(i)// }// wg.Wait()// elapsed := time.Since(start) / 1e9// fmt.Printf("\n\n%d seconds", elapsed)// }// func main() {// for i := 21; i < 120; i++ {// address := fmt.Sprintf("20.194.168.28:%d", i)// conn, err := net.Dial("tcp", address)// if err != nil {// fmt.Printf("%s failed 关闭了\n", address)// continue// }// conn.Close()// fmt.Printf("%s connected 打开了!!!\n", address)// }// }

本文来自博客园,作者:QIAOPENGJUN,转载请注明原文链接:https://www.cnblogs.com/QiaoPengjun/p/17383853.html