在 golang 中,怎么判断一个 socket 连接是否关闭?

2022-07-27 02:22:01 +08:00
 ppolanwind

golang 小白求教

4904 次点击
所在节点    Go 编程语言
26 条回复
pastor
2022-07-27 16:10:12 +08:00
@wangyu17455 这样做是 Read 能得到 err 了,但是 socket 如果本身还是活跃的,这就是误杀了

还是我来做课代表吧!

@ppolanwind 正确的做法:
1. 不要通过调用判断是否断开的方法去判断是否断开(比如 IsClosed )
2. 正常使用 Conn ,根据使用的返回值判断,比如 Read/Write 时返回了 err ,就是断开了

以上两条只是说怎么处理,实际实现 Conn 封装时通常要做的:
1. 单独一个协程处理读
2. 如果需要广播功能,单独一个协程处理写,否则可以不用单独协程、直接写就行

前面已经有人提到 keepalive ,但不够全面,仍需注意:
1. TCP 的 keepalive (传输层,4 层)只是检测连接健康状态,但不能用于判断连接的活跃状态。比如链路通顺、4 层 keepalive 是健康的,但 7 层应用层没有数据交互,这种属于僵尸连接了,对于正常的服务器,是应该踢掉这种长时间不活跃的僵尸连接的。所以 TCP 的 keepalive 选项不能解决僵尸连接的问题
2. 7 层应该自己进行 keepalive 协议包的收发比如 websocket 的 ping/pong ,来相互判断。业务协议活跃时可以节约掉 ping/pong 、一段时间没有业务协议交互再 ping/pong ,但 keepalive 间隔本来也比较大所以即使不节约这点也没关系。
3. 既然 7 层应该有自己的 keepalive ,其实 4 层的 keepalive 就没必要了
bz5314520
2022-07-27 17:38:19 +08:00
@pastor 还得是课代表
EminemW
2022-07-28 00:29:52 +08:00
读的时候判断 io.EOF
写的时候判断 broken pipe
gam2046
2022-07-28 15:44:08 +08:00
@pastor #21 有个问题想咨询课代表了,那么如何优雅的主动关闭一个 socket 呢?
pastor
2022-07-28 16:56:47 +08:00
@gam2046 不同的服务类型和框架对优雅的定义、代码的封装都不太一样,分类展开了说有点多。。给个详细点的业务类型?
lesismal
2022-08-01 19:59:05 +08:00
这个课代表,能处

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/868923

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX