title: Golang close net listener
body: <p>I am having trouble closing a listener so that I can reopen it on the same port. I am writing a proxy server that is hot-configurable - i.e what it does (redirects/blocks etc) can be adjusted on the fly. The proxy runs in a go routine. The problem I am having is when I reconfigure the listener and proxy the listener is still using that port from the previous configuration. (FYI listener is a global pointer)
  I'm trying something like:</p>
  <p>to kill the listener:</p>
  <pre><code>func KillProxy() {
      
      if listener != nil {
          log.Println(&quot; *** TRYING TO STOP THE PROXY SERVER&quot;)
          (*listener).Close()
          listener = nil
      }
  }
  </code></pre>
  <p>before reconfiguring it like:</p>
  <pre><code>log.Println(&quot;listener (S1): &quot;, listener)
  if listener == nil {
      // Start the listener to listen on the connection.
      l, err := net.Listen(CONN_TYPE, CONN_HOST + &quot;:&quot; + CONN_PORT)
  
      if err != nil {
          log.Println(&quot;error here: &quot;, err)
      }    
      listener = &amp;l //set it as a pointer to the newly created listener
  } 
  log.Println(&quot;listener (S2): &quot;, listener)
  </code></pre>
  <p>however that doesnt seem to work - I get the error:</p>
  <blockquote>
  <p>listener (S1):  </p>
  <p>error here:  listen tcp 0.0.0.0:8080: bind: address already in use</p>
  <p>listener (S2): 0xc2080015e0</p>
  </blockquote>
  <p>and then a massive stack trace that summizes to:</p>
  <blockquote>
  <p>panic: runtime error: invalid memory address or nil pointer dereference</p>
  </blockquote>
  <p>EDIT IN RESPONSE TO JIM:</p>
  <p>Interesting re pointers. OK. I am not handling waiting for the socket to close, Im not sure how that should be done. The proxy library I am using is this one: <a href="https://github.com/abourget/goproxy" rel="nofollow noreferrer">https://github.com/abourget/goproxy</a>. The order things happen is:</p>
  <pre><code>KillProxy()
  refreshProxy()
  </code></pre>
  <p>refreshProxy holds the code posted above that tries to repurpose the listener. The last thing that happens in <code>refreshProxy()</code> is:</p>
  <p><code>go http.Serve(*listener, proxy)</code></p>
  <p>So if I revert to listener being a global variable, not a pointer I can make KillProxy():</p>
  <pre><code>func KillProxy() {
      if listener != nil {
          listener.Close()
          listener = nil
      }
  }
  </code></pre>
  <p>and then setup the listener again as</p>
  <pre><code>listener, err := net.Listen(CONN_TYPE, CONN_HOST + &quot;:&quot; + CONN_PORT) 
      if err != nil {
          log.Println(&quot;error here: &quot;, err)
      }    
  </code></pre>
  <p>However I don't know how to wait and check whether the socket has closed before trying to re create the listener object?</p>