SoFunction
Updated on 2025-03-05

Detailed process of writing TCP port scanners from GoLand

Go language writing TCP scanner

TCP

  • TCP, that is, Transmission Control Protocol.

TCP Handshake

  • To establish a TCP connection (or open a port), you need 3 handshakes

Client -> Port Open -> Server

  • syn (request to establish a new connection)
  • syn-ack (Agree to create a new connection)
  • ack (indicates a response)
  • Closed Port
    • client -syn-> Server
    • Server -rst-> Client
  • If a firewall exists
    • Client β€”syn (Timeout)β€” Firewall Server

Non-concurrent TCP scanner

Create a directory and create a file in that directory

~/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 /m' to initialize a v0 or v1 module
	'go mod init /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 : module tcp-scanner
Code/go/tcp-scanner via 🐹 v1.20.3 via πŸ…’ base
➜ c
Code/go/tcp-scanner via 🐹 v1.20.3 via πŸ…’ base
➜

document

package main
import (
	"fmt"
	"net"
)
func main() {
	for i := 21; i < 120; i++ {
		address := ("20.194.168.28:%d", i)
		conn, err := ("tcp", address)
		if err != nil {
			("%s failed Closed\n", address)
			continue
		}
		()
		("%s connected open!!!\n", address)
	}
}

Concurrent TCP Scanner

package main
import (
	"fmt"
	"net"
	"sync"
	"time"
)
func main() {
	start := ()
	var wg 
	for i := 21; i < 120; i++ {
		(1)
		go func(j int) {
			defer ()
			address := ("20.194.168.28:%d", j)
			conn, err := ("tcp", address)
			if err != nil {
				("%s closed\n", address)
				return
			}
			()
			("%s is open!!!\n", address)
		}(i)
	}
	()
	elapsed := (start) / 1e9
	("\n\n%d seconds", elapsed)
}
// func main() {
// 	for i := 21; i < 120; i++ {
// 		address := ("20.194.168.28:%d", i)
// 		conn, err := ("tcp", address)
// 		if err != nil {
// ("%s failed closed\n", address)// 			continue
// 		}
// 		()
// ("%s connected is open!!!\n", address)// 	}
// }

Concurrent TCP Scanner - WORKER Pool

package main
import (
	"fmt"
	"sync"
)
func worker(ports chan int, wg *) {
	for p := range ports {
		("p", p)
		()
	}
}
func main() {
	ports := make(chan int, 100)
	var wg 
	for i := 0; i < cap(ports); i++ {
		go worker(ports, &wg)
	}
	for i := 1; i < 1024; i++ {
		(1)
		ports <- i
	}
	()
	close(ports)
}
// func main() {
// 	start := ()
// 	var wg 
// 	for i := 21; i < 120; i++ {
// 		(1)
// 		go func(j int) {
// 			defer ()
// 			address := ("20.194.168.28:%d", j)
// 			conn, err := ("tcp", address)
// 			if err != nil {
// ("%s closed\n", address)// 				return
// 			}
// 			()
// ("%s is open!!!\n", address)// 		}(i)
// 	}
// 	()
// 	elapsed := (start) / 1e9
// 	("\n\n%d seconds", elapsed)
// }
// func main() {
// 	for i := 21; i < 120; i++ {
// 		address := ("20.194.168.28:%d", i)
// 		conn, err := ("tcp", address)
// 		if err != nil {
// ("%s failed closed\n", address)// 			continue
// 		}
// 		()
// ("%s connected is open!!!\n", address)// 	}
// }

After optimization

package main
import (
	"fmt"
	"net"
	"sort"
)
func worker(ports chan int, results chan int) {
	for p := range ports {
		address := ("20.194.168.28:%d", p)
		conn, err := ("tcp", address)
		if err != nil {
			results <- 0
			continue
		}
		()
		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)
	(openports)
	(closeports)
	for _, port := range closeports {
		("%d closed\n", port)
	}
	for _, port := range openports {
		("%d opened\n", port)
	}
}
// func main() {
// 	start := ()
// 	var wg 
// 	for i := 21; i < 120; i++ {
// 		(1)
// 		go func(j int) {
// 			defer ()
// 			address := ("20.194.168.28:%d", j)
// 			conn, err := ("tcp", address)
// 			if err != nil {
// ("%s closed\n", address)// 				return
// 			}
// 			()
// ("%s is open!!!\n", address)// 		}(i)
// 	}
// 	()
// 	elapsed := (start) / 1e9
// 	("\n\n%d seconds", elapsed)
// }
// func main() {
// 	for i := 21; i < 120; i++ {
// 		address := ("20.194.168.28:%d", i)
// 		conn, err := ("tcp", address)
// 		if err != nil {
// ("%s failed closed\n", address)// 			continue
// 		}
// 		()
// ("%s connected is open!!!\n", address)// 	}
// }

This is the end of this article about writing TCP port scanner in Go (Golang). For more related contents of Go language TCP port scanner, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!