How to know TCP connection is closed in net package?

liuyanghejerry picture liuyanghejerry · Oct 5, 2012 · Viewed 69.3k times · Source

I'm implementing a small TCP server. How do I know if one of my clients closed? Should I just try to read or write and check if err is nil?

Answer

VonC picture VonC · Oct 5, 2012

That thread "Best way to reliably detect that a TCP connection is closed", using net.Conn for 'c' (also seen in utils/ping.go or locale-backend/server.go or many other instances):

one := make([]byte, 1)
c.SetReadDeadline(time.Now())
if _, err := c.Read(one); err == io.EOF {
  l.Printf(logger.LevelDebug, "%s detected closed LAN connection", id)
  c.Close()
  c = nil
} else {
  var zero time.Time
  c.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
}

For detecting a timeout, it suggests:

if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
  ...

Update 2019: tuxedo25 mentions in the comments:

In go 1.7+, zero byte reads return immediately and will never return an error.
You must read at least one byte.

See commit 5bcdd63 and go issue 15735

net: don't return io.EOF from zero byte reads