我正在玩最近去尝试制作一些服务器,它在tcp连接上响应客户端。
我的问题是如何干净地关闭服务器并中断当前在以下调用中“阻止”的go-routine
func(* TCPListener)接受?
Accept在Listener接口中实现Accept方法;它等待下一个调用并返回一个通用的Conn。
错误也很少记录。
答案 0 :(得分:4)
只需Close()
net.Listen(...)
来自{{1}}电话的net.Listener
,然后从执行的goroutine返回。
答案 1 :(得分: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
}
}
答案 2 :(得分:2)
您不一定需要额外的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)
}