GoLand編寫(xiě) TCP 端口掃描器的詳細(xì)過(guò)程
Go 語(yǔ)言編寫(xiě) TCP 掃描器
TCP
- TCP,也就是傳輸控制協(xié)議(Transmission Control Protocol)。
TCP握手
- 建立 TCP連接(或者叫打開(kāi)端口),需要3次握手
客戶端 -> 端口打開(kāi) ->服務(wù)器
- syn (請(qǐng)求建立新連接)
- syn-ack (同意創(chuàng)建新連接)
- ack (表示響應(yīng))
- 服務(wù)端端口關(guān)閉 Closed Port
- client -syn-> Server
- Server -rst-> Client
- 如果存在防火墻 Filtered Port
- Client —syn (Timeout)— Firewall Server
非并發(fā)的 TCP 掃描器
創(chuàng)建目錄并在該目錄創(chuàng)建main.go 文件
~/Code/go via ?? v1.20.3 via ?? base ? mcd tcp-scanner Code/go/tcp-scanner via ?? v1.20.3 via ?? base ? go mod init go: 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 module Run 'go help mod init' for more information. Code/go/tcp-scanner via ?? v1.20.3 via ?? base ? go mod init tcp-scanner go: creating new go.mod: module tcp-scanner Code/go/tcp-scanner via ?? v1.20.3 via ?? base ? c Code/go/tcp-scanner via ?? v1.20.3 via ?? base ?
main.go 文件
package main import ( "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 關(guān)閉了\n", address) continue } conn.Close() fmt.Printf("%s connected 打開(kāi)了?。?!\n", address) } }
并發(fā)的 TCP 掃描器
package main import ( "fmt" "net" "sync" "time" ) 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 關(guān)閉了\n", address) return } conn.Close() fmt.Printf("%s 打開(kāi)了?。?!\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 關(guān)閉了\n", address) // continue // } // conn.Close() // fmt.Printf("%s connected 打開(kāi)了?。?!\n", address) // } // }
并發(fā)的 TCP 掃描器 - WORKER 池
package main import ( "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.WaitGroup for 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 關(guān)閉了\n", address) // return // } // conn.Close() // fmt.Printf("%s 打開(kāi)了?。?!\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 關(guān)閉了\n", address) // continue // } // conn.Close() // fmt.Printf("%s connected 打開(kāi)了?。。n", address) // } // }
優(yōu)化之后
package main import ( "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 <- 0 continue } conn.Close() results <- p } } func main() { ports := make(chan int, 100) results := make(chan int) var openports []int var closeports []int for 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 := <-results if 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 關(guān)閉了\n", address) // return // } // conn.Close() // fmt.Printf("%s 打開(kāi)了?。。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 關(guān)閉了\n", address) // continue // } // conn.Close() // fmt.Printf("%s connected 打開(kāi)了?。?!\n", address) // } // }
到此這篇關(guān)于Go語(yǔ)言(Golang)編寫(xiě) TCP 端口掃描器的文章就介紹到這了,更多相關(guān)Go語(yǔ)言TCP 端口掃描器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go-zero源碼閱讀之布隆過(guò)濾器實(shí)現(xiàn)代碼
布隆過(guò)濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中。它的優(yōu)點(diǎn)是空間效率和查詢時(shí)間都比一般的算法要好的多,缺點(diǎn)是有一定的誤識(shí)別率和刪除困難,這篇文章主要介紹了go-zero源碼閱讀-布隆過(guò)濾器,需要的朋友可以參考下2023-02-02Go編程中常見(jiàn)錯(cuò)誤和不良實(shí)踐解析
這篇文章主要為大家介紹了Go編程中常見(jiàn)錯(cuò)誤和不良實(shí)踐解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01go語(yǔ)言實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的http文件服務(wù)器實(shí)例
這篇文章主要介紹了go語(yǔ)言實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的http文件服務(wù)器的方法,實(shí)例分析了Go語(yǔ)言操作http的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03Golang 實(shí)現(xiàn)Thrift客戶端連接池方式
這篇文章主要介紹了Golang 實(shí)現(xiàn)Thrift客戶端連接池方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12