分享
  1. 首页
  2. 文章

如何优雅的关闭net.Listeners

qinxiuchen · · 3802 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

使用golang做网络应用时,创建网络服务器时需要用到net.Listeners生成一个监听器,阻塞处理连接到服务器的请求,如下所示:

func main(){
 ln, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", 1234))
 if err != nil {
 log.Fatal(err)
 }
 log.Println("server start...")
 for {
 conn, err := ln.Accept()
 if err != nil {
 log.Fatal(err)
 }
 handle(conn)
 }
}

但是ln.Accept()是一个阻塞函数,我们无法在某时刻通知并令其退出(处于一个for循环之中),并且有时我们需要在关闭监听器之后做一些收尾或清理的操作。对于一个常驻进程,只能通过杀进程的方式结束,无法满足这些需求,确实不是一个优雅的处理方式。
在这里我们使用channel的思想来解决这一问题,具体实现如下:

package main
import (
 "fmt"
 "log"
 "net"
 "time"
)
var (
 quit = make(chan struct{})
 ln net.Listener
)
func main() {
 ln, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", 1234))
 if err != nil {
 log.Fatal(err)
 }
 go start()
 time.Sleep(1 * time.Second)
 stop()
 time.Sleep(1 * time.Second)
}
func start() {
 log.Println("server start...")
 for {
 conn, err := ln.Accept()
 if err != nil {
 select {
 default:
 case <-quit:
 //do something
 return
 }
 fmt.Println(err)
 }
 handle(conn)
 }
}
func stop() {
 close(quit)
 ln.Close()
}
//handle connection
func handle(conn net.Conn) {
 //......
}

增加了一个叫quit的channel,当我们关闭listener的时候也关闭此channel,监听器报错以后检测到quit已经关闭可以做一些后续处理然后再返回,达到了优雅退出的效果。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:qinxiuchen

查看原文:如何优雅的关闭net.Listeners

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
3802 次点击
1 回复 | 直到 2025年04月29日 16:47:17
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏