英文:
How can I judge a connection closed by server or client?
问题
我有一个处理接收数据的服务器,代码如下:
func handleRecv(conn *net.TCPConn) {
header := make([]byte, 2)
for {
/**阻塞直到接收到header的长度**/
n, err := io.ReadFull(conn, header)
if err != nil {
log.Error(err)
break
}
}
}
我想知道根据err
来判断连接是由服务器还是客户端关闭的。
英文:
I have a server which handle receiving data like this:
func handleRecv(conn *net.TCPConn) {
header := make([]byte, 2)
for {
/**block until recieve len(header)**/
n, err := io.ReadFull(conn, header)
if err != nil {
log.Error(err)
break
}
}
}
I would like to know which the connnection is closed by ? server or client according to err
?
答案1
得分: 2
首先,如果你在本地关闭连接,你应该在代码中知道这一点。否则,接收到io.EOF
通常表示远程端发起了关闭。
如果在本地端调用了Close()
,你会得到一个带有消息use of closed network connection
的*net.OpError
。你可能只想检查net.Error
接口,因为理论上它可以涵盖更多的错误条件。
if err, ok := err.(net.Error); ok {
fmt.Error("not an io.EOF")
fmt.Error(err.Error())
}
然而,如果在本地连接上调用了CloseRead()
(虽然这不太可能,但它有其用途),这种方法不起作用。它会返回一个io.EOF
,这就是为什么你仍然需要知道本地连接的情况。
如果连接由于超时而关闭,你将得到一个指示超时的net.Error
:
if err, ok := err.(net.Error); ok && err.Timeout() {
fmt.Error("timeout error")
}
最后,如果你关心返回的错误,你可能不想使用io.Readfull
,因为它在读取不完整时不会返回io.EOF
。只需将数据读入缓冲区并自己检查读取的字节数和错误即可。
英文:
First of all, if you're closing the connection locally, you should know about it in your code. Otherwise, receiving an io.EOF
generally signals that the remote side initiated a close.
If Close()
was called on the local side, you get a *net.OpError
with the message use of closed network connection
. You may want to just check for the net.Error
interface, since that would theoretically cover more error conditions.
if err, ok := err.(net.Error); ok {
fmt.Error("not an io.EOF")
fmt.Error(err.Error())
}
This doesn't work however if CloseRead()
was called on the local connection (which isn't very likely, but it has its uses). That will return an io.EOF
, and is why you still need to know what's happening to the connection locally.
If the connection was closed due to a timeout, you will get a net.Error
indicating the timeout:
if err, ok := err.(net.Error); ok && err.Timeout() {
fmt.Error("timeout error")
}
Finally, if you are concerned about the error returned, you may not want to use io.Readfull
, which doesn't return io.EOF
after a short read. Just read into your buffer and check the number of bytes read and the error yourself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论