goroutines /通道-不退出ctlr-c

时间:2018-07-07 05:08:49

标签: go

请考虑以下go代码,该代码是我编写的,用于从给定文件名(os.Arg [1])扫描主机名的TCP端口(os.Arg [2])。它读取每个主机名,尝试连接。如果连接失败,它将失败的主机名附加到outfile。

package main

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


func main(){
    argc := len(os.Args)
    if argc < 3 {
        fmt.Printf("Invalid usage")
        log.Fatal("Invalid usage")

    }

    stamp := time.Now().UnixNano()
    outfile := fmt.Sprintf("%s%d.txt", "/tmp/port_check", stamp)

    filename := os.Args[1] 
    file, err := os.Open(filename)
    checkerr(err)

    f, err := os.OpenFile(outfile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    checkerr(err)
    defer f.Close()

    port := os.Args[2]

    channel := make(chan string,17)
    fscanner := bufio.NewScanner(file)
    for fscanner.Scan(){
        _line := fscanner.Text()
        go check_sender(_line,port,f,channel)
    }

        _count := 0
        for out := range channel{
            fmt.Println("_count is:", _count, out)
            _count += 1
        }

        close(channel)
}


func checkerr(err error){
    if err != nil {
        fmt.Println(err)
        log.Fatal(err)
    }
}

func check_sender(sender string, port string, f *os.File, channel chan string){
    address_string := fmt.Sprintf("%s:%s", sender, port)
    _, err := net.DialTimeout("tcp", address_string,4 * time.Second)
    if err != nil {
        write_this := fmt.Sprintf("%s\n", sender)
        f.WriteString(write_this)
    }
    channel <- sender
}

为其生成一些内容以供操作:

 $ for i in `seq 1 5`; do  echo "someblog$RANDOM$RANDOM.blogspot.com"; done  > /tmp/meh.txt

当以以下方式运行时:

$ go run port_scan.go /tmp/meh.txt 80
_count is: 0 someblog50063432.blogspot.com
_count is: 1 someblog922816893.blogspot.com
_count is: 2 someblog622823698.blogspot.com
_count is: 3 someblog1074223783.blogspot.com
_count is: 4 someblog1876411881.blogspot.com
^Csignal: interrupt < ----------------------- this 

它在最后一个主机名之后挂起,直到发送ctlr-c才退出。

我希望它自己退出,我在这里做错了什么?

更新1:

    channel := make(chan string,17)
    fscanner := bufio.NewScanner(file)
+   spin := 0
    for fscanner.Scan(){
        _line := fscanner.Text()
        go check_sender(_line,port,f,channel)
+       spin += 1
    }

        _count := 0
        for out := range channel{
            fmt.Println("_count is:", _count, out)
            _count += 1
+           if _count == spin {
+               close(channel)
+           }
        }

-       close(channel)
 }

0 个答案:

没有答案