一尘不染

如何知道网络封装中TCP连接是关闭的?

go

我正在实现一个小型TCP服务器。我怎么知道我的一位客户是否关门?我应该只是尝试读取或写入并检查是否err为零?


阅读 244

收藏
2020-07-02

共1个答案

一尘不染

该线程“
的最佳方式可靠地检测TCP连接被关闭 ”,使用net.Conn了“
c”(也可见于utils/ping.golocale- backend/server.go许多其他情况下):

one := make([]byte, 1)
c.SetReadDeadline(time.Now())
if _, err := c.Read(one); err == io.EOF {
  l.Printf(logger.LevelDebug, "%s detected closed LAN connection", id)
  c.Close()
  c = nil
} else {
  var zero time.Time
  c.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
}

为了检测超时,建议:

if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
  ...

更新2019:tuxedo25在评论中提到:

在Go 1.7+中,零字节读取立即返回,并且永远不会返回错误。
您必须读取至少一个字节。

参见commit5bcdd63执行issue
15735

net:不要io.EOF从零字节读取中返回

2020-07-02