I have the following http client/server code:
Server
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Req: ", r.URL)
w.Write([]byte("OK")) // <== PROBLEMATIC LINE
// w.WriteHeader(200) // Works as expected
})
log.Fatal(http.ListenAndServe(":5008", nil))
}
Client
func main() {
client := &http.Client{}
for i := 0; i < 500; i++ {
url := fmt.Sprintf("http://localhost:5008/%02d", i)
req, _ := http.NewRequest("GET", url, nil)
_, err := client.Do(req)
if err != nil {
fmt.Println("error: ", err)
} else {
fmt.Println("success: ", i)
}
time.Sleep(10 * time.Millisecond)
}
}
When I run the client above against the server, then after 250 connections I get the following error from client.Do: error: Get http://localhost:5008/250: dial tcp: lookup localhost: no such host
and no more connections will succeed.
If I change the line in server from w.Write([]byte("OK"))
==> w.WriteHeader(200)
however then there is no limit to the amount of connections and it works as expected.
What am I missing here?
You are not closing the body. When you do any writes from the server, the connection is left open because the response has not been read yet. When you just WriteHeader, the response is done and the connection can be reused or closed.
To be completely honest, I do not know why leaving open connections causes domain lookups to fail. Based on the fact that 250 is awfully close to the round number 256, I would guess there is an artificial limitation placed by the OS that you are hitting. Perhaps the max FDs allowed is 256? Seem low, but it would explain the problem.
func main() {
client := &http.Client{}
for i := 0; i < 500; i++ {
url := fmt.Sprintf("http://localhost:5008/%02d", i)
req, _ := http.NewRequest("GET", url, nil)
resp, err := client.Do(req)
if err != nil {
fmt.Println("error: ", err)
} else {
fmt.Println("success: ", i)
}
resp.Body.Close()
time.Sleep(10 * time.Millisecond)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With