Go 编写一个 TCP 简易扫描器

2021年11月17日 1452点热度 0人点赞 0条评论
内容纲要

scanme.nmap.org 是要扫描的域名或 IP 地址。

package main

import (
    "fmt"
    "net"
    "sort"
)

func main() {
    ports := make(chan int, 100)
    results := make(chan int)
    var openports []int
    // 开启 100 个工作者线程
    for i := 0; i < cap(ports); i++ {
        go worker(ports, results)
    }
    // 向 chan 写入要扫描的端口
    go func() {
        for i := 1; i <= 1024; i++ {
            ports <- i
        }
    }()
    // 从通道中接收端口
    // 工作者线程无论执行成功与否,都必须向results 通道写入值,否则这里会阻塞
    for i := 1; i <= 1024; i++ {
        port := <-results
        if port != 0 {
            openports = append(openports, port)
        }
    }
    // 关闭所有通道
    close(ports)
    close(results)

    // 对放通的端口进行排序
    sort.Ints(openports)
    for _, port := range openports {
        fmt.Printf("%d open \n", port)
    }
}

// 工作者线程
func worker(ports, results chan int) {
    // 接收端口值,如果有则执行,没有则阻塞
    for p := range ports {
        // 扫描端口
        // 要求每次扫描,都要向 results 写入数据,失败则填写 0 ,成功则返回端口值;
        address := fmt.Sprintf("scanme.nmap.org:%d", p)
        conn, err := net.Dial("tcp", address)
        if err != nil {
            results <- 0
            return
        }
        _ = conn.Close()
        results <- p
    }
}

痴者工良

高级程序员劝退师

文章评论