go 實現(xiàn)簡易端口掃描的示例
我在代碼里定義了兩個通道,分別用于生產(chǎn)端口和限制連接數(shù),如果不限制連接數(shù),容易被對方檢測到或?qū)е聦Ψ椒?wù)器不能正常運(yùn)行。
// 生產(chǎn)端口 var port = make(chan int, 10) // 限制并發(fā)數(shù) var connect = make(chan string, 5)
可以使用net庫的Dial函數(shù)做為socket客戶端,需要注意的是要設(shè)置超時時間,因為若主機(jī)不存在,或目標(biāo)端口是關(guān)閉的,往往需要花費(fèi)數(shù)秒才返回錯誤,這樣掃描大量端口時效率會極其低下。在go中可以使用net.Dialer結(jié)構(gòu)體設(shè)置超時時間,然后在調(diào)用Dial方法:
d := net.Dialer{Timeout: time.Second}
dial, err := d.Dial("tcp", target)
只要err不等于nil,表示目標(biāo)端口是對外開放的。
完整代碼如下:
package main
import (
"fmt"
"net"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
var start, end int
var address string
fmt.Printf("請輸入目標(biāo)IP:> ")
fmt.Scan(&address)
fmt.Printf("請輸入起始端口:> ")
fmt.Scan(&start)
fmt.Printf("請輸入結(jié)束端口:> ")
fmt.Scan(&end)
wg.Add(end - start + 1)
Run(address, start, end)
wg.Wait()
fmt.Println("執(zhí)行完畢")
}
// 生產(chǎn)端口
var port = make(chan int, 10)
// 限制并發(fā)數(shù)
var connect = make(chan string, 5)
func Run(address string, start, end int) {
go func() {
for i := start; i <= end; i++ {
port <- i
}
}()
go func() {
// 消費(fèi)端口
for p := range port {
// 往通道寫入目標(biāo)地址,超過限制并發(fā)數(shù)會阻塞
connect <- fmt.Sprintf("%s:%d", address, p)
}
}()
go Connect()
}
func Connect() {
// 并發(fā)請求
for target := range connect {
// 設(shè)置超時時間
d := net.Dialer{Timeout: time.Second}
dial, err := d.Dial("tcp", target)
if err == nil {
fmt.Printf("%s 連接成功\n", target)
dial.Close()
}else{
fmt.Printf("%s 連接失敗\n", target)
}
wg.Done()
}
}
這里端口生產(chǎn)通道不是必須的,只是為了演示消費(fèi)生產(chǎn)并發(fā)模型,當(dāng)然這還是最簡單的。
在Run函數(shù)里我沒有關(guān)閉這兩個通道,按官方的說法是gc會回收不使用的通道,如果要手動關(guān)閉,可以定義defer閉包進(jìn)行close。
我本地運(yùn)行結(jié)果如下:
請輸入目標(biāo)IP:> 127.0.0.1 請輸入起始端口:> 8080 請輸入結(jié)束端口:> 8094 127.0.0.1:8080 連接成功 127.0.0.1:8081 連接成功 127.0.0.1:8082 連接成功 127.0.0.1:8083 連接成功 127.0.0.1:8084 連接成功 127.0.0.1:8085 連接成功 127.0.0.1:8086 連接成功 127.0.0.1:8087 連接成功 127.0.0.1:8088 連接成功 127.0.0.1:8089 連接成功 127.0.0.1:8090 連接成功 127.0.0.1:8091 連接成功 127.0.0.1:8092 連接成功 127.0.0.1:8093 連接失敗 127.0.0.1:8094 連接失敗 執(zhí)行完畢
這個版本比較簡陋,TCP連接過程也可以簡化,后續(xù)再寫另外一篇文章。因為最近在學(xué)rust語言,語法內(nèi)容比較多,所以后面暫時發(fā)布編程相關(guān)的文章,提升一下語法熟練度。
以上就是go 實現(xiàn)簡易端口掃描的示例的詳細(xì)內(nèi)容,更多關(guān)于go 實現(xiàn)端口掃描的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
在Go中動態(tài)替換SQL查詢中的日期參數(shù)的完整步驟
在處理數(shù)據(jù)庫查詢時,經(jīng)常需要根據(jù)不同的輸入條件動態(tài)地構(gòu)造SQL語句,尤其是在涉及日期范圍的查詢中,能夠根據(jù)實際需求調(diào)整查詢的起始和結(jié)束日期顯得尤為重要,在本文中,我將介紹如何在Go語言中實現(xiàn)動態(tài)替換SQL查詢中的日期參數(shù),需要的朋友可以參考下2024-11-11
Go?Gin框架優(yōu)雅重啟和停止實現(xiàn)方法示例
Web應(yīng)用程序中,有時需要重啟或停止服務(wù)器,無論是因為更新代碼還是進(jìn)行例行維護(hù),這時需要保證應(yīng)用程序的可用性和數(shù)據(jù)的一致性,就需要優(yōu)雅地關(guān)閉和重啟應(yīng)用程序,即不丟失正在處理的請求和不拒絕新的請求,本文將詳解如何在Go語言中使用Gin這個框架實現(xiàn)優(yōu)雅的重啟停止2024-01-01
詳解Go如何基于現(xiàn)有的context創(chuàng)建新的context
在?Golang?中,context?包提供了創(chuàng)建和管理上下文的功能,那么在GO語言中如何基于現(xiàn)有的context創(chuàng)建新的context,下面小編就來和大家詳細(xì)聊聊2024-01-01

