英文:
How to know when the net.Listener was properly closed?
问题
我有以下的代码:
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()
(对我来说不是错误)的结果。
有没有一种合适的方法来做到这一点?
英文:
I have the following code:
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
}
When l.Close()
is called, server.Serve(l)
will exit with an error. I would like to know whether this is truly an error or just the result of someone calling l.Close()
(which is non error for me).
Is there a proper way to do this?
答案1
得分: 1
一些关于TCP套接字的hack-ish方法:
read_len, err := conn.Read(request)
if err != nil {
if err.Error() == "use of closed network connection" {
// 当套接字关闭时做一些操作
break
}
在if err := server.Serve(l); err != nil {
下尝试使用if err.Error() == "use of closed network connection"
,或者在你的TCP处理函数中使用。
英文:
Some hack-ish way about TCP socket:
read_len, err := conn.Read(request)
if err != nil {
if err.Error() == "use of closed network connection" {
// Do something when socket closed
break
}
Try if err.Error() == "use of closed network connection"
under if err := server.Serve(l); err != nil {
, or in your TCP handler function.
答案2
得分: 0
使用实现io.ReadWriteCloser
接口的接口,通常会返回io.EOF
和io.ErrUnexpectedEOF
错误。net.Listener
实现了io.Closer
,所以我期望它也会返回这个错误,但不幸的是它没有遵循这个约定。相反,它返回了一个私有声明的errClosing in net.go。
net.Listener
返回的错误被包装在net.OpError
中。这个结构体有一些额外的信息可能会有帮助 - 特别是“Op”和“Err”。“Op”告诉你错误发生的位置。当你执行Close() error
时,你会得到“accept”。文档还说你也可以得到“read”和“write”。
要获取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
包使用这个函数在递增的时间间隔上重新建立连接。所以在net/http
的情况下,我会假设返回的任何错误都是调用Close() error
的结果。否则,Temporary() bool
会返回true,net/http
会为你捕获。
英文:
With interfaces that implement io.ReadWriteCloser
you typically get back an io.EOF
and io.ErrUnexpectedEOF
error. net.Listener
implements io.Closer
, so I would expect it to also return this error, but it unfortunately does not follow this convention. Instead, it returns a privately declared errClosing in net.go.
Errors returned by net.Listener
are wrapped in net.OpError
. This struct has some additional information that may be helpful - specifically "Op" and "Err". "Op" tells you where the error occurred. When you execute Close() error
you get "accept" back. The documentation says you can also get "read" and "write" back.
To get net.OpError
, you can do this:
err := server.Serve(l)
if opErr, ok := err.(*net.OpError); ok {
// opErr.Op, opErr.Err, ...
}
Or like this (assuming that net.Listener
always returns a net.OpError
):
err := server.Serve(l).(*net.OpError)
net.OptError.Err returns the original error, which would be helpful if the error was exported. Either way I don't recommend checking the string as that could break in future versions. It's better to compare the error directly to the exported error, which you don't have.
net.OptError
also has a Temporary() bool
function declared. The net/http
package uses this to re-establish the connection on a increasing interval. So in the case of net/http
I would assume that any error that returns would be a result of calling Close() error
. Otherwise Temporary() bool
would return true, which net/http
catches for you.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论