title: Is there a way to use a specific TCPConn to make HTTP requests?
body: <p>I am trying to set up a way to communicate between a central server running Go an a fleet of IoT devices (also running Go).  </p>
  
  <p>For each device, it connects to to the central server through a persistent TCPConn.  These devices are behind a router(s). The central server saves that connection and sends/receives messages through it.  Right now, this is fully functional and works.</p>
  
  <p>However, now the message passing is getting complicated enough that the utility provided by HTTP rather than pure TCP is becoming necessary.</p>
  
  <p>I have attempted to write a version of http.Transport that returns said connection.  However, I am unable to provide and return a valid connection from the the Dial/DialContext functions.</p>
  
  <p>IoT Device </p>
  
  <pre class="lang-golang prettyprint-override"><code>func main() {
  
      http.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) {
          fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
      })
  
      tcpAddr, err := net.ResolveTCPAddr("tcp", "###.###.###.###:8533")
      if err != nil {
          panic(err)
      }
  
      conn, err := net.DialTCP("tcp", nil, tcpAddr)
      if err != nil {
          panic(err)
      }
  
      err = conn.SetKeepAlive(true)
      if err != nil {
          panic(err)
      }
  
      err = conn.SetKeepAlivePeriod(time.Second * 10)
      if err != nil {
          panic(err)
      }
  
      fmt.Println("Listening")
      if err := http.ListenAndServe(":8080", nil); err != nil {
          panic(err)
      }
  }
  
  </code></pre>
  
  <p>Central Server</p>
  
  <pre class="lang-golang prettyprint-override"><code>func main() {
      tcpAddr, err := net.ResolveTCPAddr("tcp", port)
      if err != nil {
          panic(err)
      }
      listener, err := net.ListenTCP("tcp", tcpAddr)
  
      if err != nil {
          panic(err)
      }
  
      conn, err := listener.AcceptTCP()
      if err != nil {
          panic(err)
      }
      fmt.Println("Received conn, attempting to send HTTP through connection")
  
      dialFunc := func(network, addr string) (net.Conn, error) {
          return conn, nil
      }
  
      t := http.Transport{
          Dial: dialFunc,
      }
  
      client := http.Client{
          Transport: &amp;t,
      }
  
      fmt.Println("Making request")
      res, err := client.Get("http://www.shouldNotMatter.com:8080/foo") // HANGS HERE
      if err != nil {
          fmt.Println(err)
      }
  
      fmt.Println("Received response")
      defer res.Body.Close()
  
      if res.StatusCode == http.StatusOK {
          bodyBytes, err := ioutil.ReadAll(res.Body)
          if err != nil {
              panic(err)
          }
          bodyString := string(bodyBytes)
          fmt.Println(bodyString)
      } else {
          fmt.Println(res)
      }
  }
  </code></pre>
  
  <p>Upon using a debugger to see where it hangs, it seems that it gets stuck in a select statement during the pconn roundtrip.  Line 2420 in <a href="https://golang.org/src/net/http/transport.go?s=3397:10477" rel="nofollow noreferrer">https://golang.org/src/net/http/transport.go?s=3397:10477</a></p>