为了练习一些基本概念,我正在编写一个简单的端口扫描器。然而,当尝试实现 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 关注
- 116 浏览
添加回答
举报
0/150
提交
取消