博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang快速扫描
阅读量:7114 次
发布时间:2019-06-28

本文共 4405 字,大约阅读时间需要 14 分钟。

利用golang的并发优势快速扫描端口

Scanner startIp [endIp] port thread

package main  import (    "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  }  //获取下一个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")  }

转载地址:http://namhl.baihongyu.com/

你可能感兴趣的文章
H5唤起APP指南(附开源唤端库)
查看>>
[译] Swift 5.0 新特性
查看>>
自动化功能测试平台TestComplete的分布式测试教程(二)
查看>>
Chrome Network 下边栏中 Finish 的含义
查看>>
Webpack 4.x 配置教程
查看>>
Android RecyclerView多类型布局卡片解决方案
查看>>
spring-boot使用spring-security进行身份认证(2)
查看>>
Tensorflow catdog-checkpoint
查看>>
学习springBoot(9)RabbitMQ
查看>>
Python爬虫 Selenium初探
查看>>
第二节:Web前端-ASP.NET之C#基础
查看>>
银行卡 验证
查看>>
jQuery源码解析之replaceWith()/unwrap()
查看>>
交叉熵损失随记
查看>>
flask学习笔记之flask-migrate
查看>>
Swift练习题—基础控制流
查看>>
vue-router
查看>>
js基础归纳
查看>>
[译] 2019 年你应该要知道的 11 个 React UI 组件库
查看>>
技术专栏丨从原理到应用,Elasticsearch详解(上)
查看>>