中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

怎么用Go語(yǔ)言打造一款簡(jiǎn)易TCP端口掃描器

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

10年積累的網(wǎng)站制作、做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有右玉免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

TCP掃描本質(zhì)

我們?cè)谑褂肨CP進(jìn)行連接時(shí),需要知道對(duì)方機(jī)器的ip:port

正常握手

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

怎么用Go語(yǔ)言打造一款簡(jiǎn)易TCP端口掃描器

連接失敗

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

怎么用Go語(yǔ)言打造一款簡(jiǎn)易TCP端口掃描器

如果有防火墻

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

怎么用Go語(yǔ)言打造一款簡(jiǎn)易TCP端口掃描器

代碼

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

在Go中,我們通常使用net.Dial進(jìn)行TCP連接。

它就兩種情況

  • 成功:返回conn。

  • 失敗:err != nil。

普通版

相對(duì)來(lái)說(shuō),剛開始時(shí),我們可能都不是太膽大,都是先寫原型,也不考慮性能。

代碼

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, "是關(guān)閉的")             continue         }         conn.Close()         fmt.Println(address, "打開")   } }

執(zhí)行結(jié)果

怎么用Go語(yǔ)言打造一款簡(jiǎn)易TCP端口掃描器

但是這個(gè)過(guò)程是非常緩慢的。

因?yàn)閚et.Dial如果連接的是未開放的端口,一個(gè)端口可能就是20s+,所以,我們?yōu)槭裁磳W(xué)習(xí)多線程懂了把!!!

多線程版

上述是通過(guò)循環(huán)去一個(gè)個(gè)連接ip:port的,那我們就知道了,在一個(gè)個(gè)連接的位置,讓多個(gè)人去干就好了。

所以,多線程如下。

代碼

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"     //循環(huán)     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, "是關(guān)閉的", err)                 return             }             conn.Close()             fmt.Println(address, "打開")         }(j) }     //等待wg     wg.Wait()     var elapseTime = time.Now().Sub(begin)     fmt.Println("耗時(shí):", elapseTime) }

執(zhí)行結(jié)果

 怎么用Go語(yǔ)言打造一款簡(jiǎn)易TCP端口掃描器

其實(shí)是同時(shí)開啟了6W多個(gè)線程,去掃描每個(gè)ip:port。

所以耗時(shí)最長(zhǎng)的線程結(jié)束的時(shí)間,就是程序結(jié)束的時(shí)間。

感覺(jué)還行,20s+掃描完6w多個(gè)端口!!!

線程池版

上面我們簡(jiǎn)單粗暴的方式為每個(gè)ip:port都創(chuàng)建了一個(gè)協(xié)程。

雖然在Go中,理論上協(xié)程開個(gè)幾十萬(wàn)個(gè)都沒(méi)問(wèn)題,但是還是有一些壓力的。

所以我們應(yīng)該采用一種相對(duì)節(jié)約的方式進(jìn)行精簡(jiǎn)代碼,一般采用線程池方式。

本次使用的線程池包:gohive

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

簡(jiǎn)單介紹

怎么用Go語(yǔ)言打造一款簡(jiǎn)易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() {     //函數(shù)結(jié)束釋放連接     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:端口     //啟動(dòng)一個(gè)線程,用于生成ip:port,并且存放到地址管道種     go func() {         for port := 1; port <= 65535; port++ {             var address = fmt.Sprintf("%s:%d", ip, port)             //將address添加到地址管道             //fmt.Println("<-:",address)             addressChan <- address         }         //發(fā)送完關(guān)閉 addressChan 管道         close(addressChan) }()     //啟動(dòng)pool_size工人,處理addressChan種的每個(gè)地址     for work := 0; work < pool_size; work++ {         wg.Add(1)         pool.Submit(worker) }     //等待結(jié)束     wg.Wait()     //計(jì)算時(shí)間     var elapseTime = time.Now().Sub(begin)     fmt.Println("耗時(shí):", elapseTime) }

執(zhí)行結(jié)果

怎么用Go語(yǔ)言打造一款簡(jiǎn)易TCP端口掃描器

我設(shè)置的線程池大小是7w個(gè),所以也是一下子開啟6w多個(gè)協(xié)程的,但是我們已經(jīng)可以進(jìn)行線程大小約束了。

假設(shè)現(xiàn)在有這樣的去求,有100個(gè)ip,需要掃描每個(gè)ip開放的端口,如果采用簡(jiǎn)單粗暴開線程的方式.

那就是100+65535=6552300,600多w個(gè)線程,還是比較消耗內(nèi)存的,可能系統(tǒng)就會(huì)崩潰,如果采用線程池方式。

將線程池控制在50w個(gè),或許情況就會(huì)好很多。

但是有一點(diǎn)的是,在Go中,線程池通常需要配合chan使用,可能需要不錯(cuò)的基礎(chǔ)。

到此,關(guān)于“怎么用Go語(yǔ)言打造一款簡(jiǎn)易TCP端口掃描器”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

網(wǎng)頁(yè)標(biāo)題:怎么用Go語(yǔ)言打造一款簡(jiǎn)易TCP端口掃描器
文章來(lái)源:http://www.rwnh.cn/article16/pcocgg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站建設(shè)、動(dòng)態(tài)網(wǎng)站、品牌網(wǎng)站制作、網(wǎng)站策劃、標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司
法库县| 鱼台县| 万盛区| 临澧县| 通榆县| 新丰县| 新疆| 渝北区| 九江县| 卓资县| 东兴市| 新丰县| 祁阳县| 灌南县| 白山市| 清水县| 大理市| 北碚区| 松阳县| 安远县| 井研县| 囊谦县| 宜都市| 巫溪县| 黔西县| 大城县| 关岭| 广宁县| 梁河县| 额济纳旗| 舒兰市| 闸北区| 泰顺县| 阿拉善左旗| 嘉黎县| 保定市| 华亭县| 鄱阳县| 高邑县| 上饶市| 博罗县|