如何知道net.Listener何时正确关闭?

时间:2013-05-22 18:33:07

标签: networking go

我有以下代码:

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()的结果(这对我来说是非错误的)。

有没有正确的方法呢?

2 个答案:

答案 0 :(得分:1)

关于TCP套接字的一些黑客方法:

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.Error() == "use of closed network connection"下或在您的TCP处理程序函数中尝试if err := server.Serve(l); err != nil {

答案 1 :(得分:0)

使用实现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将为您捕获。