title: How do I stop a Listening server in Go
body: <p>I've been trying to find a way to stop a listening server in Go gracefully.  Because <code>listen.Accept</code> blocks it is necessary to close the listening socket to signal the end, but I can't tell that error apart from any other errors as the relevant error isn't exported.</p>
  
  <p>Can I do better than this? See <code>FIXME</code> in the code below in <code>serve()</code></p>
  
  <pre><code>package main
  
  import (
      "io"
      "log"
      "net"
      "time"
  )
  
  // Echo server struct
  type EchoServer struct {
      listen net.Listener
      done   chan bool
  }
  
  // Respond to incoming connection
  //
  // Write the address connected to then echo
  func (es *EchoServer) respond(remote *net.TCPConn) {
      defer remote.Close()
      _, err := io.Copy(remote, remote)
      if err != nil {
          log.Printf("Error: %s", err)
      }
  }
  
  // Listen for incoming connections
  func (es *EchoServer) serve() {
      for {
          conn, err := es.listen.Accept()
          // FIXME I'd like to detect "use of closed network connection" here
          // FIXME but it isn't exported from net
          if err != nil {
              log.Printf("Accept failed: %v", err)
              break
          }
          go es.respond(conn.(*net.TCPConn))
      }
      es.done &lt;- true
  }
  
  // Stop the server by closing the listening listen
  func (es *EchoServer) stop() {
      es.listen.Close()
      &lt;-es.done
  }
  
  // Make a new echo server
  func NewEchoServer(address string) *EchoServer {
      listen, err := net.Listen("tcp", address)
      if err != nil {
          log.Fatalf("Failed to open listening socket: %s", err)
      }
      es := &amp;EchoServer{
          listen: listen,
          done:   make(chan bool),
      }
      go es.serve()
      return es
  }
  
  // Main
  func main() {
      log.Println("Starting echo server")
      es := NewEchoServer("127.0.0.1:18081")
      // Run the server for 1 second
      time.Sleep(1 * time.Second)
      // Close the server
      log.Println("Stopping echo server")
      es.stop()
  }
  </code></pre>
  
  <p>This prints</p>
  
  <pre><code>2012/11/16 12:53:35 Starting echo server
  2012/11/16 12:53:36 Stopping echo server
  2012/11/16 12:53:36 Accept failed: accept tcp 127.0.0.1:18081: use of closed network connection
  </code></pre>
  
  <p>I'd like to hide the <code>Accept failed</code> message, but obviously I don't want to mask other errors <code>Accept</code> can report.  I could of course look in the error test for <code>use of closed network connection</code> but that would be really ugly.  I could set a flag saying I'm about to close and ignore errors if that was set I suppose - Is there a better way?</p>