【问题标题】:How to know when the net.Listener was properly closed?如何知道 net.Listener 何时正确关闭?
【发布时间】:2013-05-17 22:37:16
【问题描述】:

我有以下代码:

server := &http.Server{Addr: addr, Handler: r}

l, err := net.Listen("tcp", addr)
if err != nil {
    logging.Error("Failed opening socket: %s", err)
}

if err := server.Serve(l); err != nil {
    // error handling
}

当调用l.Close() 时,server.Serve(l) 将退出并出现错误。我想知道这是否真的是一个错误,或者只是某人调用l.Close() 的结果(这对我来说不是错误)。

有没有合适的方法来做到这一点?

【问题讨论】:

  • 检查错误?不过,我不确定您是否可以依靠 close() 与网卡故障区分开来,而且我无法想到 Serve() 失败的任何其他原因。
  • 这个问题和你想知道的有关how do you stop a listening server
  • 谢谢@NickCraig-Wood!

标签: networking go


【解决方案1】:

关于 TCP 套接字的一些 hack-ish 方式:

read_len, err := conn.Read(request)

if err != nil {

  if err.Error() == "use of closed network connection" { 
    // Do something when socket closed
    break
  }

if err := server.Serve(l); err != nil { 下尝试if err.Error() == "use of closed network connection",或在您的 TCP 处理函数中。

【讨论】:

  • 也考虑过这个,但正在寻找更强大的东西。谢谢。
【解决方案2】:

使用实现io.ReadWriteCloser 的接口,您通常会返回io.EOFio.ErrUnexpectedEOF 错误。 net.Listener 实现了io.Closer,所以我希望它也会返回这个错误,但不幸的是它没有遵循这个约定。相反,它返回一个私有声明的errClosing in net.go

net.Listener 返回的错误包含在net.OpError 中。这个结构有一些可能有用的附加信息——特别是“Op”和“Err”。 “Op”告诉您错误发生的位置。当您执行Close() error 时,您会得到“接受”。文档说你也可以“读”和“写”回来。

要获取net.OpError,您可以这样做:

err := server.Serve(l)
if opErr, ok := err.(*net.OpError); ok {
    // opErr.Op, opErr.Err, ...
}

或者像这样(假设net.Listener总是返回一个net.OpError):

err := server.Serve(l).(*net.OpError)

net.OptError.Err 返回原始错误,这将很有帮助如果错误被导出。无论哪种方式,我都不建议检查字符串,因为这可能会在未来的版本中中断。最好将错误直接与您没有的导出错误进行比较。

net.OptError 还声明了一个 Temporary() bool 函数。 net/httpuses this 以增加间隔重新建立连接。所以在net/http 的情况下,我会假设返回的任何错误都是调用Close() error 的结果。否则 Temporary() bool 将返回 true,net/http 会为您捕获。

【讨论】:

  • 您是否尝试运行代码示例?当我尝试它时,server.Serve(l) 在您关闭连接时不会返回 io.EOF(通过调用 l.Close())。
  • @arikfr 抱歉,我没有意识到 net.Listener 没有遵循与 net.Conn 相同的约定。关闭监听连接并不常见。做了更多挖掘,更新了答案。
猜你喜欢
  • 1970-01-01
  • 2017-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
相关资源
最近更新 更多