中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用Go語言打造一款簡易TCP端口掃描器

發布時間:2021-10-20 15:46:36 來源:億速云 閱讀:135 作者:iii 欄目:web開發

這篇文章主要介紹“怎么用Go語言打造一款簡易TCP端口掃描器”,在日常操作中,相信很多人在怎么用Go語言打造一款簡易TCP端口掃描器問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么用Go語言打造一款簡易TCP端口掃描器”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

TCP掃描本質

我們在使用TCP進行連接時,需要知道對方機器的ip:port

正常握手

連接成功的話,流程如下。

怎么用Go語言打造一款簡易TCP端口掃描器

連接失敗

有正常,就有失敗,如果被連接方關閉的話,流程如下。

怎么用Go語言打造一款簡易TCP端口掃描器

如果有防火墻

還有一種可能是,端口開放,但是防火墻攔截,流程如下。

怎么用Go語言打造一款簡易TCP端口掃描器

代碼

本質理解之后,就可以開始擼代碼了。

在Go中,我們通常使用net.Dial進行TCP連接

它就兩種情況

  • 成功:返回conn。

  • 失敗:err != nil。

普通版

相對來說,剛開始時,我們可能都不是太膽大,都是先寫原型,也不考慮性能。

代碼

package main  import (     "fmt"     "net" )  func main() {     var ip = "192.168.43.34"     for i := 21; i <= 120; i++ {         var address = fmt.Sprintf("%s:%d", ip, i)         conn, err := net.Dial("tcp", address)         if err != nil {             fmt.Println(address, "是關閉的")             continue         }         conn.Close()         fmt.Println(address, "打開")   } }

執行結果

怎么用Go語言打造一款簡易TCP端口掃描器

但是這個過程是非常緩慢的。

因為net.Dial如果連接的是未開放的端口,一個端口可能就是20s+,所以,我們為什么學習多線程懂了把!!!

多線程版

上述是通過循環去一個個連接ip:port的,那我們就知道了,在一個個連接的位置,讓多個人去干就好了。

所以,多線程如下。

代碼

package main  import (     "fmt"     "net"     "sync"     "time" )  func main() {      var begin =time.Now()     //wg     var wg sync.WaitGroup     //ip     var ip = "192.168.99.112"     //var ip = "192.168.43.34"     //循環     for j := 21; j <= 65535; j++ {         //添加wg         wg.Add(1)         go func(i int) {             //釋放wg             defer wg.Done()             var address = fmt.Sprintf("%s:%d", ip, i)             //conn, err := net.DialTimeout("tcp", address, time.Second*10)             conn, err := net.Dial("tcp", address)             if err != nil {                 //fmt.Println(address, "是關閉的", err)                 return             }             conn.Close()             fmt.Println(address, "打開")         }(j) }     //等待wg     wg.Wait()     var elapseTime = time.Now().Sub(begin)     fmt.Println("耗時:", elapseTime) }

執行結果

 怎么用Go語言打造一款簡易TCP端口掃描器

其實是同時開啟了6W多個線程,去掃描每個ip:port。

所以耗時最長的線程結束的時間,就是程序結束的時間。

感覺還行,20s+掃描完6w多個端口!!!

線程池版

上面我們簡單粗暴的方式為每個ip:port都創建了一個協程。

雖然在Go中,理論上協程開個幾十萬個都沒問題,但是還是有一些壓力的。

所以我們應該采用一種相對節約的方式進行精簡代碼,一般采用線程池方式。

本次使用的線程池包:gohive

地址:https://github.com/loveleshsharma/gohive

簡單介紹

怎么用Go語言打造一款簡易TCP端口掃描器

代碼

package main  //線程池方式 import (     "fmt"     "github.com/loveleshsharma/gohive"     "net"     "sync"     "time" )  //wg var wg sync.WaitGroup  //地址管道,100容量 var addressChan = make(chan string, 100)  //工人 func worker() {     //函數結束釋放連接     defer wg.Done()     for {         address, ok := <-addressChan         if !ok {             break         }         //fmt.Println("address:", address)         conn, err := net.Dial("tcp", address)         //conn, err := net.DialTimeout("tcp", address, 10)         if err != nil {             //fmt.Println("close:", address, err)             continue         }         conn.Close()         fmt.Println("open:", address) } } func main() {     var begin = time.Now()     //ip     var ip = "192.168.99.112"     //線程池大小     var pool_size = 70000     var pool = gohive.NewFixedSizePool(pool_size)      //拼接ip:端口     //啟動一個線程,用于生成ip:port,并且存放到地址管道種     go func() {         for port := 1; port <= 65535; port++ {             var address = fmt.Sprintf("%s:%d", ip, port)             //將address添加到地址管道             //fmt.Println("<-:",address)             addressChan <- address         }         //發送完關閉 addressChan 管道         close(addressChan) }()     //啟動pool_size工人,處理addressChan種的每個地址     for work := 0; work < pool_size; work++ {         wg.Add(1)         pool.Submit(worker) }     //等待結束     wg.Wait()     //計算時間     var elapseTime = time.Now().Sub(begin)     fmt.Println("耗時:", elapseTime) }

執行結果

怎么用Go語言打造一款簡易TCP端口掃描器

我設置的線程池大小是7w個,所以也是一下子開啟6w多個協程的,但是我們已經可以進行線程大小約束了。

假設現在有這樣的去求,有100個ip,需要掃描每個ip開放的端口,如果采用簡單粗暴開線程的方式.

那就是100+65535=6552300,600多w個線程,還是比較消耗內存的,可能系統就會崩潰,如果采用線程池方式。

將線程池控制在50w個,或許情況就會好很多。

但是有一點的是,在Go中,線程池通常需要配合chan使用,可能需要不錯的基礎。

到此,關于“怎么用Go語言打造一款簡易TCP端口掃描器”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汉阴县| 东兴市| 沐川县| 临高县| 乌鲁木齐县| 延安市| 桂林市| 沧州市| 南充市| 霍城县| 涞水县| 游戏| 新蔡县| 固镇县| 茂名市| 定边县| 河北省| 石台县| 广宁县| 修水县| 瑞安市| 丰镇市| 基隆市| 孟村| 开远市| 昂仁县| 余庆县| 许昌县| 社旗县| 民丰县| 双牌县| 青田县| 刚察县| 惠水县| 德州市| 泗水县| 基隆市| 茌平县| 石棉县| 东丽区| 大宁县|