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

如何中断执行 (*TCPListener) Accept 的 goroutine?

如何中断执行 (*TCPListener) Accept 的 goroutine?

Go
慕仙森 2021-06-10 18:43:03
我最近在玩 go 并尝试制作一些服务器来响应 tcp 连接上的客户端。我的问题是如何干净地关闭服务器并中断当前在以下调用中“阻塞”的 go-routinefunc (*TCPListener) 接受吗?根据Accept的文档Accept在Listener接口中实现了Accept方法;它等待下一次调用并返回一个通用的 Conn。这些错误也几乎没有记录。
查看完整描述

3 回答

?
侃侃无极

TA贡献2051条经验 获得超10个赞

TCP侦听器截止日期

您不一定需要额外的 go 例程(不断接受),只需指定一个Deadline.


for 例子:


for {


    // Check if someone wants to interrupt accepting

    select {

    case <- someoneWantsToEndMe: 

        return // runs into "defer listener.Close()"

    default: // nothing to do

    }


    // Accept with Deadline

    listener.SetDeadline(time.Now().Add(1 * time.Second)

    conn, err := listener.Accept()

    if err != nil {

        // TODO: Could do some err checking (to be sure it is a timeout), but for brevity

        continue

    }


    go handleConnection(conn)

}


查看完整回答
反对 回复 2021-06-28
?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

只需Close()net.Listener你从一开始net.Listen(...)呼叫,从正在执行的够程返回。


查看完整回答
反对 回复 2021-06-28
?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

这就是我要找的。也许将来会帮助某人。注意使用 select 和 "c" 通道将它与退出通道结合起来


    ln, err := net.Listen("tcp", ":8080")

    if err != nil {

        // handle error

    }

    defer ln.Close()

    for {

        type accepted struct {

            conn net.Conn

            err  error

        }

        c := make(chan accepted, 1)

        go func() {

            conn, err := ln.Accept()

            c <- accepted{conn, err}

        }()

        select {

        case a := <-c:

            if a.err != nil {

                // handle error

                continue

            }

            go handleConnection(a.conn)

        case e := <-ev:

            // handle event

            return

        }

    }


查看完整回答
反对 回复 2021-06-28
  • 3 回答
  • 0 关注
  • 278 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信