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 ( "flag" "fmt" "net" "os" "strconv" "strings")/**扫描地址*/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,4) for i := 0; i < flag.NArg(); i++ { args = append(args,flag.Arg(i)) } //启动扫描线程 go runScan() //启动结果写入线程 go writeResult() //参数处理 processFlag(args) //等待退出指令 <-clo fmt.Println("Exit")}总结
以上是内存溢出为你收集整理的用golang写的简单端口扫描器全部内容,希望文章能够帮你解决用golang写的简单端口扫描器所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)