一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術(shù)及教程分享平臺!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Golang - 手把手教你用Go語言打造一款簡易TCP端口掃描器

手把手教你用Go語言打造一款簡易TCP端口掃描器

2021-01-10 23:22Go語言進(jìn)階學(xué)習(xí)Go進(jìn)階者 Golang

這次呢, 咱們來實(shí)現(xiàn)一個簡單的TCP端口掃描器!也來體驗(yàn)一下黑客的風(fēng)采!TCP掃描本質(zhì)就是我們在使用TCP進(jìn)行連接時,需要知道對方機(jī)器的ip:port

 前言

Hey,大家好呀,我是碼農(nóng),星期八。

這次呢, 咱們來實(shí)現(xiàn)一個簡單的TCP端口掃描器!

也來體驗(yàn)一下黑客的風(fēng)采!

TCP掃描本質(zhì)

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

正常握手

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

手把手教你用Go語言打造一款簡易TCP端口掃描器

連接失敗

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

手把手教你用Go語言打造一款簡易TCP端口掃描器

如果有防火墻

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

手把手教你用Go語言打造一款簡易TCP端口掃描器

代碼

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

在Go中,我們通常使用net.Dial進(jìn)行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, "是關(guān)閉的"

            continue 

        } 

        conn.Close() 

        fmt.Println(address, "打開"

  } 

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

手把手教你用Go語言打造一款簡易TCP端口掃描器

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

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

多線程版

上述是通過循環(huán)去一個個連接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" 

    //循環(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("耗時:", elapseTime) 

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

 手把手教你用Go語言打造一款簡易TCP端口掃描器

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

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

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

線程池版

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

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

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

本次使用的線程池包: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() { 

    //函數(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:端口 

    //啟動一個線程,用于生成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) 

}() 

    //啟動pool_size工人,處理addressChan種的每個地址 

    for work := 0; work < pool_size; work++ { 

        wg.Add(1) 

        pool.Submit(worker) 

    //等待結(jié)束 

    wg.Wait() 

    //計(jì)算時間 

    var elapseTime = time.Now().Sub(begin

    fmt.Println("耗時:", elapseTime) 

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

手把手教你用Go語言打造一款簡易TCP端口掃描器

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

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

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

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

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

總結(jié)

本篇更偏向于樂趣篇,了解一下好玩的玩意。

其實(shí)還可以通過net.DialTimeout連接ip:port,這個可以設(shè)置超時時間,比如超時5s就判定端口未開放。

此處就不做舉例了。

咱們主要使用三種方式來實(shí)現(xiàn)功能。

  • 正常版,沒有并發(fā),速度很慢。
  • 多協(xié)程版,并發(fā),性能很高,但是協(xié)程太多可能會崩潰。
  • 協(xié)程池版,并發(fā),性能高,協(xié)程數(shù)量可控。

通常情況下,如果基礎(chǔ)可以,更推薦使用協(xié)程池方式。

用微笑告訴別人,今天的我比昨天強(qiáng),今后也一樣。

原文地址:https://mp.weixin.qq.com/s/YEBtew4-kPRmAK0VYx7bOA

 

延伸 · 閱讀

精彩推薦
  • GolangGolang中Bit數(shù)組的實(shí)現(xiàn)方式

    Golang中Bit數(shù)組的實(shí)現(xiàn)方式

    這篇文章主要介紹了Golang中Bit數(shù)組的實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨(dú)尊11682021-06-09
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • GolangGolang通脈之?dāng)?shù)據(jù)類型詳情

    Golang通脈之?dāng)?shù)據(jù)類型詳情

    這篇文章主要介紹了Golang通脈之?dāng)?shù)據(jù)類型,在編程語言中標(biāo)識符就是定義的具有某種意義的詞,比如變量名、常量名、函數(shù)名等等,Go語言中標(biāo)識符允許由...

    4272021-11-24
  • Golanggolang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法

    golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • Golanggolang的httpserver優(yōu)雅重啟方法詳解

    golang的httpserver優(yōu)雅重啟方法詳解

    這篇文章主要給大家介紹了關(guān)于golang的httpserver優(yōu)雅重啟的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,...

    helight2992020-05-14
  • Golanggolang如何使用struct的tag屬性的詳細(xì)介紹

    golang如何使用struct的tag屬性的詳細(xì)介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細(xì)介紹,從例子說起,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網(wǎng)11352020-05-21
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggo日志系統(tǒng)logrus顯示文件和行號的操作

    go日志系統(tǒng)logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統(tǒng)logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
主站蜘蛛池模板: 7mav视频| 欧美一级裸片又黄又裸 | 免费看60分钟大片视频播放 | 2022最新a精品视频在线观看 | 3d动漫h在线观看网站蜜芽 | 亚洲精品国产成人99久久 | 欧洲男同直粗无套播放视频 | 羞羞视频污 | 日本韩国推理片免费观看网站 | 调教全程肉动画片在线观看 | 亚州精品永久观看视频 | 99久久免费国产特黄 | 国产日韩欧美在线观看不卡 | 丝袜足控免费网站xx动漫漫画 | 喷潮女王cytherea全部视频 | 无限资源在线观看完整版免费下载 | 国产福利你懂的 | 思敏1一5集国语版免费观看 | 法国老妇性xx在线播放 | 女教师被女同学调教成脚奴 | 蝴蝶传媒免费安装 | 天堂a视频 | 私人影院免费 | 欧美一区二区三区在线观看免费 | 国产91影院 | 五月天色小说 | 无套日出白浆在线播放 | 欧美日韩国产手机在线观看视频 | 射逼网 | 女同学高中你下面好紧 | 亚洲另类中文字幕 | 大ji巴好好爽好深网站 | japanesepooping脱粪 | 男女羞羞的视频 | 秋霞鲁丝影院久久人人综合 | 九九爱这里只有精品 | 甜蜜惩罚小说 | 国产三级精品久久三级国专区 | 高h生子双性美人受 | 亚洲人成伊人成综合网久久 | 欧美日韩一区视频 |