前话

最近痴迷于Golang这个新兴语言,因为它是强类型编译型语言,可以直接编译成三大平台的二进制执行文件,可以直接运行无需其他依赖环境。而且Golang独特的goroutine使得多线程任务执行如new一个对象般简单。

带着为学习理解Golang的好奇心情,我试着写了个端口扫描器。

github项目链接如下, 更多的实用工具我会慢慢添加。

https://github.com/pwcong/go-tools

源码

package main

import (
"flag"
"fmt"
"net"
"os"
"regexp"
"strconv"
"strings"
"sync"
) var port int
var portRange string var parallelCounts int func init() { flag.IntVar(&port, "p", 80, "port")
flag.StringVar(&portRange, "r", "", "range ports. format is <from>~<to>. eg. 100~200")
flag.IntVar(&parallelCounts, "n", 1, "parallel counts") // 修改提示信息
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "\nUsage: %s [Options] <IP>\n\nOptions:\n\n", os.Args[0])
flag.PrintDefaults()
} flag.Parse() } func printOpeningPort(port int) { fmt.Println("port " + strconv.Itoa(port) + " is opening") } func checkPort(ip net.IP, port int, wg *sync.WaitGroup, parallelChan *chan int) { defer wg.Done() tcpAddr := net.TCPAddr{
IP: ip,
Port: port,
} conn, err := net.DialTCP("tcp", nil, &tcpAddr) if err == nil {
printOpeningPort(port)
conn.Close() } <-*parallelChan } func main() { args := flag.Args() if len(args) != 1 {
flag.Usage()
} else { ip := net.ParseIP(flag.Arg(0)) // 用于协程任务控制
wg := sync.WaitGroup{} if portRange != "" { matched, _ := regexp.Match(`^\d+~\d+$`, []byte(portRange)) if !matched { flag.Usage() } else { portSecs := strings.Split(portRange, "~") startPort, err1 := strconv.Atoi(portSecs[0])
endPort, err2 := strconv.Atoi(portSecs[1]) if err1 != nil || err2 != nil || startPort < 1 || endPort < 2 || endPort <= startPort || parallelCounts < 1 {
flag.Usage()
} else { wg.Add(endPort - startPort + 1) // 用于控制协程数
parallelChan := make(chan int, parallelCounts) for i := startPort; i <= endPort; i++ { parallelChan <- 1 go checkPort(ip, i, &wg, &parallelChan) } wg.Wait() } } } else { wg.Add(1) parallelChan := make(chan int) go func() {
parallelChan <- 1
}() go checkPort(ip, port, &wg, &parallelChan) wg.Wait() } } }

运行结果

  1. 执行 go build ./main.go, 生成二进制文件
  2. 运行二进制文件,结果如下:
    $ port-scanner.exe
    
    Usage: E:\Program Files\GoPath\bin\port-scanner.exe [Options] <IP>
    
    Options:
    
      -n int
    parallel counts (default 1)
    -p int
    port (default 80)
    -r string
    range ports. format is <from>~<to>. eg. 100~200 $ port-scanner.exe -p 80 127.0.0.1
    port 80 is opening $ port-scanner.exe -r 1~100 -n 50 127.0.0.1
    port 80 is opening

Golang 写一个端口扫描器的更多相关文章

  1. java编写一个端口扫描器

    好久没写java了,学的时候,也没学习网络编程这一块,无意中看到了一本书,于是小小复习一下java,写个端口扫描器,玩玩吧,网上这种小公具有的是,就是自己无聊写着玩玩. 源代码如下: 共两个类,比较简 ...

  2. 再议perl写多线程端口扫描器

    再议perl写多线程端口扫描器 http://blog.csdn.net/sx1989827/article/details/4642179 perl写端口多线程扫描器 http://blog.csd ...

  3. 使用golang写一个redis-cli

    使用golang写一个redis-cli 0. redis通信协议 redis的客户端(redis-cli)和服务端(redis-server)的通信是建立在tcp连接之上, 两者之间数据传输的编码解 ...

  4. mac/unix系统:C++实现一个端口扫描器

    在比较早以前,我用过S扫描器, 以及大名鼎鼎的nmap扫描器, 可以快速扫描某个主机开放的端口, 今天使用C实现这样一个软件, 编译环境为Mac, 系统版本10.11.6: #include < ...

  5. GoWorld – 用Golang写一个分布式可扩展、可热更的游戏服务器

    GoWorld代码:https://github.com/xiaonanln/goworld Golang具有运行效率高.内存安全等优良特性,因此是非常适合用来进行服务器开发.使用Golang开发游戏 ...

  6. 参考MySQL Internals手册,使用Golang写一个简单解析binlog的程序

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. MySQL作为最流行的开源关系型数据库,有大量的拥趸.其生态已经相当完善,各项特性在圈内都有大量研究.每次新特性发布,都会 ...

  7. golang写一个简单的爬虫

    package main import( "fmt" "io/ioutil" "net/http" ) func gethtml(url s ...

  8. Python与Hack之window下运行带参数的Python脚本,实现一个简单的端口扫描器

    1.前提是:windows已经配置好Python的环境变量: 2.进入cmd命令行模式: **输入python命令,检测是否环境配置好:显示这样说明配置环境变量没问题 **用cd命令进入Python脚 ...

  9. 【技术分享】手把手教你使用PowerShell内置的端口扫描器

    [技术分享]手把手教你使用PowerShell内置的端口扫描器 引言 想做端口扫描,NMAP是理想的选择,但是有时候NMAP并不可用.有的时候仅仅是想看一下某个端口是否开放.在这些情况下,PowerS ...

随机推荐

  1. 精简计算UITableView文本高度

    精简计算UITableView文本高度 本人视频教程系类   iOS中CALayer的使用 最终效果: 核心源码(计算文本高度的类) NSString+StringHeight.h 与 NSStrin ...

  2. Docker 命令总结

    1 启动镜像 docker run -i -t centos /bin/bash

  3. docker 自制CentOS 6-lnp镜像

    环境准备 1台centos 6.5镜像虚拟机  febootstrap.docker febootstrap 安装 yum install -y yum-priorities && r ...

  4. rman恢复方案和oracle异机恢复

    这篇文章主要介绍了rman恢复方案和oracle异机恢复,需要的朋友可以参考下 注:①恢复的前提是已经做好备份②完全恢复数据库是数据库遇到故障,在恢复时候没有丢失任何已经提交事物数据的恢复不完全恢复数 ...

  5. PHP设计模式系列 - 建造者模式

    什么是建造者模式 建造者模式主要是为了消除其它对象复杂的创建过程. 设计场景 有一个用户的UserInfo类,创建这个类,需要创建用户的姓名,年龄,金钱等信息,才能获得用户具体的信息结果. 创建一个U ...

  6. Apache Hadoop各版本发布的SVN地址

    http://svn.apache.org/repos/asf/hadoop/common/tags

  7. iOS: 聊聊 Designated Initializer(指定初始化函数):NS_DESIGNATED_INITIALIZER

    总结:指定函数的调用规则: 初始化函数的调用顺序与初始化顺序相反. 上面关于指定初始化的规则讲了那么多,其实可以归纳为两点: 便利初始化函数只能调用自己类中的其他初始化方法 指定初始化函数才有资格调用 ...

  8. socket.io+angular.js+express.js做个聊天应用(二)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/www19940501a/article/details/27585321 接着上一篇 我用的开发工具 ...

  9. virtualbox+vagrant学习-4-Vagrantfile-2-Configuration Version

    Configuration Version 配置版本是vagrant 1.1+能够与vagrant 1.0保持向后兼容的机制.同时引入了引人注目的新特性和配置选项. 如果你运行了vagrant ini ...

  10. nginx学习要点记录

    IO多路复用: 1.轻量 2.cpu亲和性:把CPU核心和nginx工作进程绑定,把每个worker进程固定在一个CPU上执行,减少切换cpu的cache miss,获得更好的性能 3.IO多路复用e ...