11

我最近在玩 go 并尝试创建一些服务器来响应 tcp 连接上的客户端。

我的问题是我如何干净地关闭服务器并中断当前在以下调用中“阻塞”的 go-routine

func (*TCPListener) 接受?

根据Accept的文档

Accept 实现了 Listener 接口中的 Accept 方法;它等待下一次调用并返回一个通用的 Conn。

这些错误也很少被记录。

4

3 回答 3

5

只需Close()从调用中net.Listener获取net.Listen(...)并从执行的 goroutine 返回。

于 2013-09-16T10:12:30.413 回答
5

TCPListener 截止日期

您不一定需要额外的 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)
}
于 2018-02-07T10:35:52.993 回答
2

这是我一直在寻找的。也许将来会帮助某人。注意使用 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
        }
    }
于 2013-09-23T21:59:24.383 回答