為了練習一些基本概念,我正在編寫一個簡單的端口掃描器。然而,當嘗試實現 goroutines 時,程序會出現恐慌,并且出現分段錯誤:Scanning ports{Port:139 State:Open}{Port:135 State:Open}{Port:136 State:Closed}{Port:131 State:Closed}{Port:131 State:Open}{Port:134 State:Closed}{Port:134 State:Open}panic: runtime error: invalid memory address or nil pointer dereference[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4eb26a]goroutine 20 [running]:main.scanPort(0x52033b, 0x3, 0x52203e, 0xf, 0x83) /home/athos/Projects/go-tutorial/scanner.go:33 +0x1eacreated by main.main /home/athos/Projects/go-tutorial/scanner.go:41 +0xf1panic: runtime error: invalid memory address or nil pointer dereference[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4eb26a]goroutine 23 [running]:main.scanPort(0x52033b, 0x3, 0x52203e, 0xf, 0x86) /home/athos/Projects/go-tutorial/scanner.go:33 +0x1eacreated by main.main /home/athos/Projects/go-tutorial/scanner.go:41 +0xf1exit status 2這是我的代碼:package mainimport ( "fmt" "net" "strconv" "sync" "time")var wg sync.WaitGrouptype scanResult struct { Port int State string}func scanPort(protocol, hostname string, port int) { defer wg.Done() result := scanResult{Port: port} socket := hostname + ":" + strconv.Itoa(port) conn, err := net.DialTimeout(protocol, socket, 2*time.Second) if err != nil { result.State = "Closed" fmt.Printf("%+v\n", result) } result.State = "Open" fmt.Printf("%+v\n", result) // Defers: FILO data structure defer conn.Close()}func main() { fmt.Println("Scanning ports") for i := 130; i <= 145; i++ { wg.Add(1) go scanPort("tcp", "192.168.200.103", i) } // Wait for goroutines to complete wg.Wait()}誰能幫我看看我做錯了什么?
1 回答

開心每一天1111
TA貢獻1836條經驗 獲得超13個贊
net.DialTimeout()返回連接和錯誤,您正確檢查錯誤是否不是nil,但即使有錯誤,您只需打印并繼續。
如果存在非nil錯誤,則不應(絕不能)使用返回的連接,因為它可能是nil無效值。如果有錯誤,檢查/打印并返回,不要嘗試使用conn.
所以簡單地返回:
if err != nil {
result.State = "Closed"
fmt.Printf("%+v\n", result)
return
}
此外,如果沒有錯誤,您可以“安排”立即關閉連接,延遲。defer如果您在函數中關閉連接的最后一件事,則使用毫無意義。
所以它應該是這樣的:
conn, err := net.DialTimeout(protocol, socket, 2*time.Second)
if err != nil {
result.State = "Closed"
fmt.Printf("%+v\n", result)
return
}
defer conn.Close()
result.State = "Open"
fmt.Printf("%+v\n", result)
- 1 回答
- 0 關注
- 118 瀏覽
添加回答
舉報
0/150
提交
取消