为了账号安全,请及时绑定邮箱和手机立即绑定

这种恐慌的原因是什么?

这种恐慌的原因是什么?

Go
青春有我 2022-07-25 11:17:35
为了练习一些基本概念,我正在编写一个简单的端口扫描器。然而,当尝试实现 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)


查看完整回答
反对 回复 2022-07-25
  • 1 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号