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
?
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.