脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Golang - GoLand编写 TCP 端口扫描器的详细过程

GoLand编写 TCP 端口扫描器的详细过程

2023-05-09 13:38QIAOPENGJUN Golang

TCP,也就是传输控制协议(Transmission Control Protocol),这篇文章主要介绍了Go语言(Golang)编写 TCP 端口扫描器,需要的朋友可以参考下

Go 语言编写 TCP 扫描器

TCP

  • TCP,也就是传输控制协议(Transmission Control Protocol)。

TCP握手

  • 建立 TCP连接(或者叫打开端口),需要3次握手

客户端 -> 端口打开 ->服务器

  • syn (请求建立新连接)
  • syn-ack (同意创建新连接)
  • ack (表示响应)
  • 服务端端口关闭 Closed Port
    • client -syn-> Server
    • Server -rst-> Client
  • 如果存在防火墙 Filtered Port
    • Client —syn (Timeout)— Firewall Server

非并发的 TCP 扫描器

创建目录并在该目录创建main.go 文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
~/Code/go via v1.20.3 via base
→ mcd tcp-scanner
Code/go/tcp-scanner via v1.20.3 via base
go mod init
go: cannot determine module path for source directory /Users/qiaopengjun/Code/go/tcp-scanner (outside GOPATH, module path must be specified)
Example usage:
    'go mod init example.com/m' to initialize a v0 or v1 module
    'go mod init example.com/m/v2' to initialize a v2 module
Run 'go help mod init' for more information.
Code/go/tcp-scanner via v1.20.3 via base
go mod init tcp-scanner
go: creating new go.mod: module tcp-scanner
Code/go/tcp-scanner via v1.20.3 via base
→ c
Code/go/tcp-scanner via v1.20.3 via base

main.go 文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main
import (
    "fmt"
    "net"
)
func main() {
    for i := 21; i < 120; i++ {
        address := fmt.Sprintf("20.194.168.28:%d", i)
        conn, err := net.Dial("tcp", address)
        if err != nil {
            fmt.Printf("%s failed 关闭了\n", address)
            continue
        }
        conn.Close()
        fmt.Printf("%s connected 打开了!!!\n", address)
    }
}

并发的 TCP 扫描器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package main
import (
    "fmt"
    "net"
    "sync"
    "time"
)
func main() {
    start := time.Now()
    var wg sync.WaitGroup
    for i := 21; i < 120; i++ {
        wg.Add(1)
        go func(j int) {
            defer wg.Done()
            address := fmt.Sprintf("20.194.168.28:%d", j)
            conn, err := net.Dial("tcp", address)
            if err != nil {
                fmt.Printf("%s 关闭了\n", address)
                return
            }
            conn.Close()
            fmt.Printf("%s 打开了!!!\n", address)
        }(i)
    }
    wg.Wait()
    elapsed := time.Since(start) / 1e9
    fmt.Printf("\n\n%d seconds", elapsed)
}
// func main() {
//  for i := 21; i < 120; i++ {
//      address := fmt.Sprintf("20.194.168.28:%d", i)
//      conn, err := net.Dial("tcp", address)
//      if err != nil {
//          fmt.Printf("%s failed 关闭了\n", address)
//          continue
//      }
//      conn.Close()
//      fmt.Printf("%s connected 打开了!!!\n", address)
//  }
// }

并发的 TCP 扫描器 - WORKER 池

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package main
import (
    "fmt"
    "sync"
)
func worker(ports chan int, wg *sync.WaitGroup) {
    for p := range ports {
        fmt.Println("p", p)
        wg.Done()
    }
}
func main() {
    ports := make(chan int, 100)
    var wg sync.WaitGroup
    for i := 0; i < cap(ports); i++ {
        go worker(ports, &wg)
    }
    for i := 1; i < 1024; i++ {
        wg.Add(1)
        ports <- i
    }
    wg.Wait()
    close(ports)
}
// func main() {
//  start := time.Now()
//  var wg sync.WaitGroup
//  for i := 21; i < 120; i++ {
//      wg.Add(1)
//      go func(j int) {
//          defer wg.Done()
//          address := fmt.Sprintf("20.194.168.28:%d", j)
//          conn, err := net.Dial("tcp", address)
//          if err != nil {
//              fmt.Printf("%s 关闭了\n", address)
//              return
//          }
//          conn.Close()
//          fmt.Printf("%s 打开了!!!\n", address)
//      }(i)
//  }
//  wg.Wait()
//  elapsed := time.Since(start) / 1e9
//  fmt.Printf("\n\n%d seconds", elapsed)
// }
// func main() {
//  for i := 21; i < 120; i++ {
//      address := fmt.Sprintf("20.194.168.28:%d", i)
//      conn, err := net.Dial("tcp", address)
//      if err != nil {
//          fmt.Printf("%s failed 关闭了\n", address)
//          continue
//      }
//      conn.Close()
//      fmt.Printf("%s connected 打开了!!!\n", address)
//  }
// }

优化之后

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package main
import (
    "fmt"
    "net"
    "sort"
)
func worker(ports chan int, results chan int) {
    for p := range ports {
        address := fmt.Sprintf("20.194.168.28:%d", p)
        conn, err := net.Dial("tcp", address)
        if err != nil {
            results <- 0
            continue
        }
        conn.Close()
        results <- p
    }
}
func main() {
    ports := make(chan int, 100)
    results := make(chan int)
    var openports []int
    var closeports []int
    for i := 0; i < cap(ports); i++ {
        go worker(ports, results)
    }
    go func() {
        for i := 1; i < 1024; i++ {
            ports <- i
        }
    }()
    for i := 1; i < 1024; i++ {
        port := <-results
        if port != 0 {
            openports = append(openports, port)
        } else {
            closeports = append(closeports, port)
        }
    }
    close(ports)
    close(results)
    sort.Ints(openports)
    sort.Ints(closeports)
    for _, port := range closeports {
        fmt.Printf("%d closed\n", port)
    }
    for _, port := range openports {
        fmt.Printf("%d opened\n", port)
    }
}
// func main() {
//  start := time.Now()
//  var wg sync.WaitGroup
//  for i := 21; i < 120; i++ {
//      wg.Add(1)
//      go func(j int) {
//          defer wg.Done()
//          address := fmt.Sprintf("20.194.168.28:%d", j)
//          conn, err := net.Dial("tcp", address)
//          if err != nil {
//              fmt.Printf("%s 关闭了\n", address)
//              return
//          }
//          conn.Close()
//          fmt.Printf("%s 打开了!!!\n", address)
//      }(i)
//  }
//  wg.Wait()
//  elapsed := time.Since(start) / 1e9
//  fmt.Printf("\n\n%d seconds", elapsed)
// }
// func main() {
//  for i := 21; i < 120; i++ {
//      address := fmt.Sprintf("20.194.168.28:%d", i)
//      conn, err := net.Dial("tcp", address)
//      if err != nil {
//          fmt.Printf("%s failed 关闭了\n", address)
//          continue
//      }
//      conn.Close()
//      fmt.Printf("%s connected 打开了!!!\n", address)
//  }
// }

到此这篇关于Go语言(Golang)编写 TCP 端口扫描器的文章就介绍到这了,更多相关Go语言TCP 端口扫描器内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/QiaoPengjun/archive/2023/05/09/17383853.html

延伸 · 阅读

精彩推荐
  • GolangGolang操作命令行的几种方式总结

    Golang操作命令行的几种方式总结

    这篇文章主要介绍了Golang操作命令行的几种方式总结,文章通过围主题思想展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下...

    jiaxwu​​​​​​​10412022-11-17
  • Golang一文详解go同步协程的必备工具WaitGroup

    一文详解go同步协程的必备工具WaitGroup

    这篇文章主要为大家介绍了一文详解go同步协程的必备工具WaitGroup使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早...

    starrySky11852023-03-21
  • GolangGo语言基础语法之结构体及方法详解

    Go语言基础语法之结构体及方法详解

    结构体类型可以用来保存不同类型的数据,也可以通过方法的形式来声明它的行为。本文将介绍go语言中的结构体和方法,以及“继承”的实现方法...

    测试开发小记6242021-11-16
  • GolangGo语言for range(按照键值循环)遍历操作

    Go语言for range(按照键值循环)遍历操作

    这篇文章主要介绍了Go语言for range(按照键值循环)遍历操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    wilsonyx7622021-03-03
  • Golanggolang 函数返回chan类型的操作

    golang 函数返回chan类型的操作

    这篇文章主要介绍了golang 函数返回chan类型的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    CodeMechine4972021-06-07
  • GolangWindows下安装VScode 并使用及中文配置方法

    Windows下安装VScode 并使用及中文配置方法

    这篇文章主要介绍了Windows下安装VScode 并使用及中文配置的方法详解,本文通过图文并茂的形式给大家介绍,对大家的学习或工作具有一定的参考借鉴价值...

    肖帝5932020-06-08
  • Golang如何解决goland,idea全局搜索快捷键失效问题

    如何解决goland,idea全局搜索快捷键失效问题

    这篇文章主要介绍了如何解决goland,idea全局搜索快捷键失效问题,快捷键失效,可能是快捷键冲突,也或者是快捷键被修改成其他了。在settings下查看快捷键...

    峰啊疯了5282022-09-13
  • Golang在go语言中安装与使用protobuf的方法详解

    在go语言中安装与使用protobuf的方法详解

    protobuf以前只支持C++, Python和Java等语言, Go语言出来后, 作为亲儿子, 那有不支持的道理呢? 这篇文章主要给大家介绍了关于在go语言中使用protobuf的相关资料,...

    Dr_Zhang14192020-05-08