以下是一个示例代码,演示了如何使用Go语言根据给定的网段拆分出IP地址,并使用多线程判断主机是否存活并进行端口探测。代码中还包含了异常判断。\n\ngo\npackage main\n\nimport (\n\t"fmt"\n\t"net"\n\t"strconv"\n\t"sync"\n\t"time"\n)\n\nconst (\n\tstartPort = 1\n\tendPort = 65535\n\ttimeout = 1 * time.Second\n)\n\nfunc main() {\n\tipRange := "192.168.0.1/24" // 你的网段\n\nips := getIPsFromRange(ipRange)\n\tfmt.Printf("拆分的IP地址:%v\n", ips)\n\n\tvar wg sync.WaitGroup\n\tfor _, ip := range ips {\n\t wg.Add(1)\n\t go func(ip string) {\n\t defer wg.Done()\n\n\t isAlive := checkHostAlive(ip)\n\t if isAlive {\n\t fmt.Printf("主机 %s 存活\n", ip)\n\t scanPorts(ip)\n\t } else {\n\t fmt.Printf("主机 %s 不可达\n", ip)\n\t }\n\t }(ip)\n\t}\n\n\twg.Wait()\n\tfmt.Println("完成")\n}\n\n// 从网段中获取所有的IP地址\nfunc getIPsFromRange(ipRange string) []string {\n\tip, subnet, _ := net.ParseCIDR(ipRange)\n\n\tvar ips []string\n\tfor ip := ip.Mask(subnet.Mask); subnet.Contains(ip); inc(ip) {\n\t ips = append(ips, ip.String())\n\t}\n\n\treturn ips\n}\n\n// IP地址自增\nfunc inc(ip net.IP) {\n\tfor j := len(ip) - 1; j >= 0; j-- {\n\t ip[j]++\n\t if ip[j] > 0 {\n\t break\n\t }\n\t}\n}\n\n// 检查主机是否存活\nfunc checkHostAlive(ip string) bool {\n\tconn, err := net.DialTimeout("ip4:icmp", ip, timeout)\n\t if err != nil {\n\t return false\n\t }\n\n\tconn.Close()\n\treturn true\n}\n\n// 端口探测\nfunc scanPorts(ip string) {\n\tfor port := startPort; port <= endPort; port++ {\n\t target := ip + ":" + strconv.Itoa(port)\n\t conn, err := net.DialTimeout("tcp", target, timeout)\n\t if err == nil {\n\t fmt.Printf("主机 %s 的端口 %d 是开放的\n", ip, port)\n\t conn.Close()\n\t }\n\t}\n}\n\n\n在上面的示例代码中,首先定义了一个常量startPortendPort,分别表示要扫描的端口范围。timeout常量表示连接超时时间。\n\ngetIPsFromRange函数根据给定的网段拆分出所有的IP地址,并返回一个字符串数组。\n\ncheckHostAlive函数用于检查主机是否存活。它使用net.DialTimeout函数尝试建立与主机的ICMP连接,如果连接成功,则表示主机存活。\n\nscanPorts函数用于进行端口探测。它使用net.DialTimeout函数尝试建立与目标主机指定端口的TCP连接,如果连接成功,则表示该端口开放。\n\n在main函数中,先调用getIPsFromRange函数获取所有的IP地址,然后使用一个sync.WaitGroup来等待所有的协程完成。\n\n对于每个IP地址,启动一个协程来检查主机存活并进行端口探测。如果主机存活,则输出相应的信息并调用scanPorts函数进行端口探测;否则,输出主机不可达的信息。\n\n最后,调用Wait方法等待所有的协程完成,并输出"完成"的信息。\n\n注意,上述代码中的端口探测使用的是阻塞的方式,可以根据实际需求进行改进,使用非阻塞方式或并发方式进行端口探测。同时,对于大规模的扫描任务,可能需要考虑使用更高效的方式来提高性能。


原文地址: https://www.cveoy.top/t/topic/pILo 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录