我有以下代码:
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()
的结果(这对我来说是非错误的)。
有没有正确的方法呢?
答案 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.EOF
和io.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/http
包uses this以越来越大的间隔重新建立连接。因此,在net/http
的情况下,我会假设返回的任何错误都是调用Close() error
的结果。否则Temporary() bool
将返回true,net/http
将为您捕获。