go语言制作端口扫描器
GO语言编写的TCP端口扫描器,本人的第一个GO程序。
Git@OSC:http://git.oschina.net/youshusoft/GoScanner
使用命令:
ScannerstartIp[endIp]portthread
参数说明:
startIp 开始IP
endIp 结束IP,可选,不输入表示只扫描startIp
port 扫描端口,单个端口:3389;多个端口:1433,3389;连续端口:135-3389
thread 最大并发线程数,最高2048
扫描结果保存在同目录下的result.txt中,每次启动都会清掉之前的内容。
例子一:
Scanner58.96.172.2258.96.172.22080512
扫描58.96.172.22到58.96.172.220中的80端口,最大并发线程512。
例子二:
Scanner58.96.172.2258.96.172.22021,5631512
扫描58.96.172.22到58.96.172.220中的21和5631端口,最大并发线程512。
例子三:
Scanner58.96.172.2258.96.172.2201-520512
扫描58.96.172.22到58.96.172.220中的1到520端口,最大并发线程512。
例子四:
Scanner58.96.172.221-520512
扫描58.96.172.22中的1到520端口,最大并发线程512。
packagemain import( "fmt" "strconv" "flag" "strings" "net" "os" ) /** 扫描地址 */ varipAddrschanstring=make(chanstring) //扫描结果 varresultchanstring=make(chanstring) //线程数 varthreadchanint=make(chanint) varnowThreadint; //关闭程序 varclochanbool=make(chanbool) //保存结果 funcwriteResult(){ fileName:="result.txt" fout,err:=os.Create(fileName) iferr!=nil{ //文件创建失败 fmt.Println(fileName+"createerror") } deferfout.Close() s,ok:=<-result for;ok;{ fout.WriteString(s+"\r\n") s,ok=<-result } //通知进程退出 clo<-true; } //根据线程参数启动扫描线程 funcrunScan(){ t,ok:=<-thread nowThread=t; ifok{ fori:=0;i<nowThread;i++{ goscan(strconv.Itoa(i)) } } //等待线程终止 for;<-thread==0;{ nowThread-- ifnowThread==0{ //全部线程已终止,关闭结果写入,退出程序 close(result) break } } } /** 扫描线程 */ funcscan(threadIdstring){ s,ok:=<-ipAddrs for;ok;{ fmt.Println("[thread-"+threadId+"]scan:"+s) _,err:=net.Dial("tcp",s) iferr==nil{ //端口开放 result<-s } s,ok=<-ipAddrs } fmt.Println("[thread-"+threadId+"]end") thread<-0; } //获取下一个IP funcnextIp(ipstring)string{ ips:=strings.Split(ip,".") variint; fori=len(ips)-1;i>=0;i--{ n,_:=strconv.Atoi(ips[i]) ifn>=255{ //进位 ips[i]="1" }else{ //+1 n++ ips[i]=strconv.Itoa(n) break } } ifi==-1{ //全部IP段都进行了进位,说明此IP本身已超出范围 return""; } ip="" leng:=len(ips) fori:=0;i<leng;i++{ ifi==leng-1{ ip+=ips[i] }else{ ip+=ips[i]+"." } } returnip } //生成IP地址列表 funcprocessIp(startIp,endIpstring)[]string{ varips=make([]string,0) for;startIp!=endIp;startIp=nextIp(startIp){ ifstartIp!=""{ ips=append(ips,startIp) } } ips=append(ips,startIp) returnips } //处理参数 funcprocessFlag(arg[]string){ //开始IP,结束IP varstartIp,endIpstring //端口 varports[]int=make([]int,0) index:=0 startIp=arg[index] si:=net.ParseIP(startIp) ifsi==nil{ //开始IP不合法 fmt.Println("'startIp'Settingerror") return } index++ endIp=arg[index] ei:=net.ParseIP(endIp) if(ei==nil){ //未指定结束IP,即只扫描一个IP endIp=startIp }else{ index++ } tmpPort:=arg[index] ifstrings.Index(tmpPort,"-")!=-1{ //连续端口 tmpPorts:=strings.Split(tmpPort,"-") varstartPort,endPortint varerrerror startPort,err=strconv.Atoi(tmpPorts[0]) iferr!=nil||startPort<1||startPort>65535{ //开始端口不合法 return } iflen(tmpPorts)>=2{ //指定结束端口 endPort,err=strconv.Atoi(tmpPorts[1]) iferr!=nil||endPort<1||endPort>65535||endPort<startPort{ //结束端口不合法 fmt.Println("'endPort'Settingerror") return } }else{ //未指定结束端口 endPort=65535 } fori:=0;startPort+i<=endPort;i++{ ports=append(ports,startPort+i) } }else{ //一个或多个端口 ps:=strings.Split(tmpPort,",") fori:=0;i<len(ps);i++{ p,err:=strconv.Atoi(ps[i]) iferr!=nil{ //端口不合法 fmt.Println("'port'Settingerror") return } ports=append(ports,p) } } index++ t,err:=strconv.Atoi(arg[index]) if(err!=nil){ //线程不合法 fmt.Println("'thread'Settingerror") return } //最大线程2048 ift<1{ t=1; }elseift>2048{ t=2048; } //传送启动线程数 thread<-t //生成扫描地址列表 ips:=processIp(startIp,endIp) il:=len(ips) fori:=0;i<il;i++{ pl:=len(ports) forj:=0;j<pl;j++{ ipAddrs<-ips[i]+":"+strconv.Itoa(ports[j]) } } close(ipAddrs) } funcmain(){ flag.Parse() ifflag.NArg()!=3&&flag.NArg()!=4{ //参数不合法 fmt.Println("Parametererror") return } //获取参数 args:=make([]string,0,4) fori:=0;i<flag.NArg();i++{ args=append(args,flag.Arg(i)) } //启动扫描线程 gorunScan() //启动结果写入线程 gowriteResult() //参数处理 processFlag(args) //等待退出指令 <-clo; fmt.Println("Exit") }
以上所述就是本文的全部内容了,希望大家能够喜欢。