迭代多行变量到 return 所有 ips

Iterating over a multiline variable to return all ips

我正在尝试为初学者 golang 项目构建一个简单的端口扫描器 大多数代码都按预期工作,但我遇到了问题 ipv4_gen()函数到return逐行生成的所有ips 并将它们传递给另一个函数以当前扫描它们 ipv4_gen() Returns 只有第一行有一种方法可以逐行遍历 ip 变量到 return 所有 ips 吗?

package main

import (
    "fmt"
    "log"
    "net"
    "strconv"
    "time"
)

func ipv4_gen() string {
    ip, ipnet, err := net.ParseCIDR("192.168.1.1/24")
    if err != nil {
        log.Fatal(err)
    }
    for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
        return ip.String()
    }
    return ip.String()
}

func inc(ip net.IP) {
    for j := len(ip) - 1; j >= 0; j-- {
        ip[j]++
        if ip[j] > 0 {
            break
        }
    }
}

func port_scanner(host string) {
    port := strconv.Itoa(80)
    conn, err := net.DialTimeout("tcp", host+":"+port, 1*time.Second)
    if err == nil {
        fmt.Println("Host:", conn.RemoteAddr().String(), "open")
        conn.Close()
    }
}

func main() {
    port_scanner(ipv4_gen())
}

这里是 link 如果你想要 运行 代码 https://play.golang.org/p/YWvgnowZzhI

为了 return 一个函数的多个结果(尤其是当可能生成数千个结果时)在 Go 中惯用的是使用 channel.

package main

import (
    "fmt"
    "log"
    "net"
    "strconv"
    "time"
)

func ipv4_gen(out chan string) {
    ip, ipnet, err := net.ParseCIDR("192.168.1.1/24")
    if err != nil {
        log.Fatal(err)
    }
    for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
        out <- ip.String()
    }
    close(out)
}

func inc(ip net.IP) {
    for j := len(ip) - 1; j >= 0; j-- {
        ip[j]++
        if ip[j] > 0 {
            break
        }
    }
}

func port_scanner(host string) {
    port := strconv.Itoa(80)
    conn, err := net.DialTimeout("tcp", host+":"+port, 1*time.Second)
    if err == nil {
        fmt.Println("Host:", conn.RemoteAddr().String(), "open")
        conn.Close()
    }
}

func main() {
    ips := make(chan string)
    go ipv4_gen(ips)
    for s := range ips {
        port_scanner(s)
    }
}

如果我正确理解了你的问题,那么这应该可行。

package main

import (
    "fmt"
    "log"
    "net"
    "os"
    "strconv"
    "time"
)

func ipv4_gen(ch chan<- string) {
    ip, ipnet, err := net.ParseCIDR("192.168.1.1/24")
    if err != nil {
        log.Fatal(err)
    }
    for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
        ch <- ip.String()
    }
    close(ch)
}

func inc(ip net.IP) {
    for j := len(ip) - 1; j >= 0; j-- {
        if ip[j]++; ip[j] > 0 {
            break
        }
    }
}

func port_scanner(hosts <-chan string) {
    for host := range hosts {
        port := strconv.Itoa(80)
        conn, err := net.DialTimeout("tcp", host+":"+port, 1*time.Second)
        if err != nil {
            fmt.Fprintln(os.Stderr, err)
            continue
        }
        fmt.Println("Host:", conn.RemoteAddr().String(), "open")
        conn.Close()
    }
}

func main() {
    ip := make(chan string)
    go ipv4_gen(ip)
    port_scanner(ip)
}