利用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")
}

golang快速扫描的更多相关文章

  1. 如何快速扫描C段(网站快照、后台识别/登录、目录扫描)

    1.C段扫描 C类地址范围从 192.0.0.1 到 223.255.255.254 ,192转换成二进制就是1100000:223转换成二进制就是1101111:所以说网络地址的最高位肯定是110开 ...

  2. 索引快速扫描(index fast full scan)

    一.索引快速扫描(index fast full scan) 索引快速全扫描(INDEX FAST FULL SCAN)和索引全扫描(INDEX  FULL SCAN)极为类似,它也适用于所有类型的B ...

  3. Golang快速入门

    Go语言简介: Golang 简称 Go,是一个开源的编程语言,Go是从2007年末由 Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian L ...

  4. 端口快速扫描程序(c#版 一次可发起1000个连接)

    前言 为了探测本机或对方开放了哪些端口,需要用到端口扫描程序.扫描端口的原理很简单:就是尝试连接对方:如果成功,对方就开放了此端口.扫描程序的关键是速度,如果一次只能发起几个连接,显然速度太慢.如果对 ...

  5. JAVA开发者的Golang快速指南

    Golang作为Docker.Kubernetes和OpenShift等一些酷辣新技术的首选编程语言,越来越受欢迎.尤其它们都是开源的,很多情况下,开源是非常有价值的.深入学习阅Golang等源代码库 ...

  6. 快速扫描文本文件,统计行数,并返回每一行的索引位置(Delphi、C#)

    由项目需要,需要扫描1200万行的文本文件.经网友的指点与测试,发现C#与Delphi之间的差距并不大.不多说,列代码测试: 下面是Delphi的代码: //遍历文件查找回车出现的次数 functio ...

  7. win10如何快速扫描-上海IT外包

     第一步,点击Windows图标  第二步点击所有应用  第三步点击Windows附件  最后点击Windows传真和扫描就可以了 上海IT33_专业的it外包一站式服务商,为多家企业提供it ...

  8. nmap 快速扫描所有端口

    nmap -sT -sV -Pn -v xxx.xxx.xxx.xxx nmap -sS -p 1-65535 -v 192.168.1.254参数:-sS    TCP SYN扫描    nmap ...

  9. PJzhang:端口快速扫描工具masscan

    猫宁!!! 参考:https://www.freebuf.com/sectool/112583.html github地址: https://github.com/robertdavidgraham/ ...

随机推荐

  1. HDU - 4456 cdq

    题意:给一个矩阵,两种操作1:修改单点的权值,2:查询和某个点曼哈顿距离小于r点的权值和 题解:先旋转坐标轴,(x,y)->(x-y,x+y)然后就变成了cdq分治裸题,子矩阵和和单点修改一维时 ...

  2. React文档(五)组件和props

    组件可以让你将UI分割成独立的,可复用的模块,然后考虑将每个模块彼此隔离.从概念上理解,组件就像js中的函数.他们接受随意的输入(被称为props)然后返回React元素来描述屏幕上应该出现什么. 函 ...

  3. Version Control System

    Version  Control System(版本控制系统),是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统.版本控制系统不仅可以应用于软件源代码的文本文件,而且可以对任何类型 ...

  4. flask-系统介绍及环境搭建1

    1.系统介绍 前台首页-电影筛选-电影列表- 播放详情-评论:收藏-搜索-注册-登录-会员中心(修改会员资料,查看评论记录,登录日志,收藏电影). 后台-标签-电影管理-预告-会员-评论-收藏-日志- ...

  5. C++三大特性 封装 继承 多态

    C++ 三大特性 封装,继承,多态 封装 定义:封装就是将抽象得到的数据和行为相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成类,其中数据和函数都是类的成员,目的在于将对 ...

  6. Farm Irrigation(非常有意思的并查集)

    Farm Irrigation Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Tot ...

  7. DBCC - Undocumented commands

    These commands may affect system performance and/or force table-level locks.There is no guarantee th ...

  8. Oracle12c中配置实例参数和修改容器数据库(CDB)及可插拔数据库(PDB)

    Oracle12c中的多宿主选项允许一个容器数据库(CDB)容纳多个独立的可插拔数据库(PDB).本文将展示如何配置实例参数和修改容器数据库(CDB)及可插拔数据库(PDB).1. 配置CDB中的实例 ...

  9. qt 调用zlib压缩与解压缩功能

    Zlib是一种免费且通用的压缩库,由于Zlib压缩效果比LZW好,而且解压缩速度快,更重要的是商业软件中使用Zlib不需要缴纳版权费,所以很多游戏都使用Zlib压缩资源文件. Zlib是由Jean-l ...

  10. laravel使用使用 Php Artisan Tinker 实现模型的增删改查

    tinker命令: php artisan tinker 查阅数据库数据: App\User::count(); App\User::where('username', 'samuel')->f ...