1 回答

TA貢獻1815條經驗 獲得超6個贊
一旦 for 循環完成,您的 main 函數將退出。如果 main 函數退出,所有由它啟動的 goroutines 也會退出。您需要等待 goroutine 完成。例如,這可以通過 來實現sync.WaitGroup。
package main
import (
"fmt"
"net"
"sync"
"time"
)
func main() {
// This will help you to keep track of the goroutines
var wg sync.WaitGroup
for i := 1; i <= 9000; i++ {
// Increment the counter for each goroutine you start.
wg.Add(1)
go func(j int) {
// Make sure the wait group counter is decremented when the goroutine exits
defer wg.Done()
address := fmt.Sprintf("127.0.0.1:%d", j)
conn, err := net.DialTimeout("tcp", address, 2 * time.Second)
if err != nil {
return
}
conn.Close()
fmt.Printf("%d open\n", j)
}(i)
}
// Wait for all goroutines to finish before exiting main
wg.Wait()
}
編輯:對我來說,由于缺少文件描述符,代碼原樣不起作用。以下功能可靠地工作。
它需要更好的錯誤處理,但確實有效
package main
import (
"fmt"
"log"
"net"
"sync"
"time"
)
var minPort = 1
var maxPort = 65535
var timeout = 2 * time.Second
const parallel = 50
func main(){
fmt.Println("portscan called")
// Create a buffered channel with a size equal to the number of goroutines
ctrl := make(chan int, parallel)
// Keep track of the currently active goroutines
var wg sync.WaitGroup
for p := 1; p <= parallel; p++ {
wg.Add(1)
// Start a goroutine...
go func(p int) {
log.Printf("Starting goroutine %d", p)
// ...listening to the control channel.
// For every value this goroutine reads from the
// channel...
for i := range ctrl {
address := fmt.Sprintf("127.0.0.1:%d", i)
// ...try to conncet to the port.
conn, err := net.DialTimeout("tcp", address, timeout)
if err == nil {
conn.Close()
log.Printf("[%3d]: %5d open", p, i)
}
// TBD: ERROR HANDLING!!!
}
// If the channel is closed, this goroutine is done.
wg.Done()
log.Printf("[%3d]: Exiting", p)
}(p)
}
// Fill the control channel with values.
// If the channel is full, the write operation
// to the channel will block until one of the goroutines
// reads a value from it.
for i := minPort; i <= maxPort; i++ {
ctrl <- i
}
// We have sent all values, so the channel can be closed.
// The goroutines will finish their current connection attempt,
// notice that the channel is closed and will in turn call wg.Done().
close(ctrl)
// When all goroutines have announced that they are done, we can exit.
wg.Wait()
}
- 1 回答
- 0 關注
- 195 瀏覽
添加回答
舉報