返回顶部
首页 > 资讯 > 后端开发 > GO >主 goroutine Golang 中无法接收沿通道发送的最后一个值
  • 320
分享到

主 goroutine Golang 中无法接收沿通道发送的最后一个值

2024-02-09 11:02:51 320人浏览 独家记忆
摘要

主 Goroutine golang 中无法接收沿通道发送的最后一个值。这是由于当通道被关闭后,goroutine 无法再次接收到新的值。相反,它将一直阻塞在接收操作上,直到通道中的所

Goroutine golang 中无法接收沿通道发送的最后一个值。这是由于当通道被关闭后,goroutine 无法再次接收到新的值。相反,它将一直阻塞在接收操作上,直到通道中的所有值都被接收完毕。这是 Golang 中的一种设计选择,旨在避免在接收操作过程中可能出现的死情况。因此,在编写 Golang 程序时,我们需要特别注意这一点,以避免潜在的问题和错误。

问题内容

给定 golang 中的 tcp 端口扫描器。 2个实现,第一个是我的,第二个来自golang书。假设第二个是 100% 可行的,正如许多读者之前测试的那样。但似乎两者都有相同的问题:在结果通道中发送的最后一个值无法在主协程中接收,它陷入无限等待来自通道的值,尽管该值实际上已发送。 一些观察:当端口数量少于 21 个时,它按预期工作;当金额超过1000时,未收到的金额增加到10左右。 我不明白为什么。

书中的实现

func worker(ports, results chan int) {
    for p := range ports {
        address := fmt.Sprintf("scanme.nmap.org:%d", p)
        conn, err := net.Dial("tcp", address)
        if err != nil {
            results <- 0
            fmt.Println("sent", p)
            continue
        }
        conn.Close()
        results <- p
        fmt.Println("sent", p)
    }
}

func main() {
    ports := make(chan int, 100)
    results := make(chan int)

    var openports []int

    for i := 0; i < cap(ports); i++ {
        go worker(ports, results)
    }

    go func() {
        for i := 1; i <= 50; i++ {
            ports <- i
        }
    }()

    for i := 0; i < 50; i++ {
        port := <-results // after 49 it gets stuck infinitely, never proceed further
        fmt.Println("received", port, i)
        if port != 0 {
            openports = append(openports, port)
        }
    }

    close(ports)
    close(results)

    sort.Ints(openports)

    fmt.Println(openports)

}

解决方法

通过向 net.Dialer 添加超时已解决该问题

func worker(ports, results chan int) {
    dialer := net.Dialer{Timeout: time.Second}

    for p := range ports {
        address := fmt.Sprintf("scanme.nmap.org:%d", p)
        conn, err := dialer.Dial("tcp", address)
        if err != nil {
            results <- 0
            continue
        }

        conn.Close()
        results <- p
    }
}

以上就是主 goroutine Golang 中无法接收沿通道发送的最后一个值的详细内容,更多请关注编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: 主 goroutine Golang 中无法接收沿通道发送的最后一个值

本文链接: https://www.lsjlt.com/news/562473.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 主 goroutine Golang 中无法接收沿通道发送的最后一个值
    主 goroutine Golang 中无法接收沿通道发送的最后一个值。这是由于当通道被关闭后,goroutine 无法再次接收到新的值。相反,它将一直阻塞在接收操作上,直到通道中的所...
    99+
    2024-02-09
  • GoLang Socket.io 发送的数据无法在 React 中接收
    积累知识,胜过积蓄金银!毕竟在Golang开发的过程中,会遇到各种各样的问题,往往都是一些细节知识点还没有掌握好而导致的,因此基础知识点的积累是很重要的。下面本文《GoLang Socket.io ...
    99+
    2024-04-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作