您好,登錄后才能下訂單哦!
GO語言編寫的TCP端口掃描器,本人的第一個GO程序。
Git@OSC:http://git.oschina.net/youshusoft/GoScanner
使用命令:
Scanner startIp [endIp] port thread
參數說明:
startIp 開始IP
endIp 結束IP,可選,不輸入表示只掃描startIp
port 掃描端口,單個端口:3389;多個端口:1433,3389;連續端口:135-3389
thread 最大并發線程數,最高2048
掃描結果保存在同目錄下的 result.txt 中,每次啟動都會清掉之前的內容。
例子一:
Scanner 58.96.172.22 58.96.172.220 80 512
掃描58.96.172.22到58.96.172.220中的80端口,最大并發線程512。
例子二:
Scanner 58.96.172.22 58.96.172.220 21,5631 512
掃描58.96.172.22到58.96.172.220中的21和5631端口,最大并發線程512。
例子三:
Scanner 58.96.172.22 58.96.172.220 1-520 512
掃描58.96.172.22到58.96.172.220中的1到520端口,最大并發線程512。
例子四:
Scanner 58.96.172.22 1-520 512
掃描58.96.172.22中的1到520端口,最大并發線程512。
package main import ( "fmt" "strconv" "flag" "strings" "net" "os" ) /** 掃描地址 */ var ipAddrs chan string = make(chan string) //掃描結果 var result chan string = make(chan string) //線程數 var thread chan int = make(chan int) var nowThread int; //關閉程序 var clo chan bool = make(chan bool) //保存結果 func writeResult(){ fileName := "result.txt" fout,err := os.Create(fileName) if err != nil{ //文件創建失敗 fmt.Println(fileName + " create error") } defer fout.Close() s,ok := <- result for ;ok;{ fout.WriteString(s + "\r\n") s,ok = <- result } //通知進程退出 clo <- true; } //根據線程參數啟動掃描線程 func runScan(){ t,ok := <- thread nowThread = t; if ok{ for i := 0;i < nowThread;i++{ go scan(strconv.Itoa(i)) } } //等待線程終止 for;<-thread == 0;{ nowThread-- if nowThread == 0{ //全部線程已終止,關閉結果寫入,退出程序 close(result) break } } } /** 掃描線程 */ func scan(threadId string){ s,ok := <-ipAddrs for;ok;{ fmt.Println("[thread-" + threadId + "] scan:" + s) _,err := net.Dial("tcp",s) if err == nil{ //端口開放 result <- s } s,ok = <-ipAddrs } fmt.Println("[thread-" + threadId + "] end") thread <- 0; } //獲取下一個IP func nextIp(ip string) string{ ips := strings.Split(ip,".") var i int; for i = len(ips) - 1;i >= 0;i--{ n,_ := strconv.Atoi(ips[i]) if n >= 255{ //進位 ips[i] = "1" }else{ //+1 n++ ips[i] = strconv.Itoa(n) break } } if i == -1{ //全部IP段都進行了進位,說明此IP本身已超出范圍 return ""; } ip = "" leng := len(ips) for i := 0;i < leng;i++{ if i == leng -1{ ip += ips[i] }else{ ip += ips[i] + "." } } return ip } //生成IP地址列表 func processIp(startIp,endIp string) []string{ var ips = make([]string,0) for ;startIp != endIp;startIp = nextIp(startIp){ if startIp != ""{ ips = append(ips,startIp) } } ips = append(ips,startIp) return ips } //處理參數 func processFlag(arg []string){ //開始IP,結束IP var startIp,endIp string //端口 var ports []int = make([]int,0) index := 0 startIp = arg[index] si := net.ParseIP(startIp) if si == nil{ //開始IP不合法 fmt.Println("'startIp' Setting error") return } index++ endIp = arg[index] ei := net.ParseIP(endIp) if(ei == nil){ //未指定結束IP,即只掃描一個IP endIp = startIp }else{ index++ } tmpPort := arg[index] if strings.Index(tmpPort,"-") != -1{ //連續端口 tmpPorts := strings.Split(tmpPort,"-") var startPort,endPort int var err error startPort,err = strconv.Atoi(tmpPorts[0]) if err != nil || startPort < 1 || startPort > 65535{ //開始端口不合法 return } if len(tmpPorts) >= 2{ //指定結束端口 endPort,err = strconv.Atoi(tmpPorts[1]) if err != nil || endPort < 1 || endPort > 65535 || endPort < startPort{ //結束端口不合法 fmt.Println("'endPort' Setting error") return } }else{ //未指定結束端口 endPort = 65535 } for i := 0;startPort + i <= endPort;i++{ ports = append(ports,startPort + i) } }else{ //一個或多個端口 ps := strings.Split(tmpPort,",") for i := 0;i < len(ps);i++{ p,err := strconv.Atoi(ps[i]) if err != nil{ //端口不合法 fmt.Println("'port' Setting error") return } ports = append(ports,p) } } index++ t,err := strconv.Atoi(arg[index]) if(err != nil){ //線程不合法 fmt.Println("'thread' Setting error") return } //最大線程2048 if t < 1{ t = 1; }else if t > 2048{ t = 2048; } //傳送啟動線程數 thread <- t //生成掃描地址列表 ips := processIp(startIp,endIp) il := len(ips) for i := 0; i < il;i++{ pl := len(ports) for j := 0;j < pl;j++{ ipAddrs <- ips[i] + ":" + strconv.Itoa(ports[j]) } } close(ipAddrs) } func main(){ flag.Parse() if flag.NArg() != 3 && flag.NArg() != 4{ //參數不合法 fmt.Println("Parameter error") return } //獲取參數 args := make([]string,0,4) for i := 0;i < flag.NArg();i++{ args = append(args,flag.Arg(i)) } //啟動掃描線程 go runScan() //啟動結果寫入線程 go writeResult() //參數處理 processFlag(args) //等待退出指令 <- clo; fmt.Println("Exit") }
以上所述就是本文的全部內容了,希望大家能夠喜歡。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。