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 mainimport ("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;}//擷取下一個IPfunc 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")}
以上所述就是本文的全部內容了,希望大家能夠喜歡。