在进行HTTP请求时出现了错误。

huangapple go评论131阅读模式
英文:

go error on doing HTTP requests

问题

当运行以下HTTP客户端对Web服务器进行压力测试时,出现了奇怪的错误,想知道是什么原因。Go的版本是go1.8.1 linux/amd64,运行在Ubuntu 14.04上,内存为16GB。

以下是代码运行时的输出:

  1. $ go run te2.go
  2. 563.904492ms
  3. Get http://10.3.0.6/small: dial tcp 10.3.0.6:80: connect: cannot assign requested address
  4. Get http://10.3.0.6/small: dial tcp 10.3.0.6:80: connect: cannot assign requested address
  5. Get http://10.3.0.6/small: dial tcp 10.3.0.6:80: connect: cannot assign requested address
  6. panic: runtime error: invalid memory address or nil pointer dereference
  7. [signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x5e3b27]
  8. goroutine 140284 [running]:
  9. main.httpGet(0x0)
  10. /home/jon/learn/go/te2.go:27 +0x107
  11. created by main.main
  12. /home/jon/learn/go/te2.go:45 +0xd3
  13. panic: runtime error: invalid memory address or nil pointer dereference
  14. [signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x5e3b27]
  15. goroutine 140375 [running]:
  16. main.httpGet(0x0)
  17. /home/jon/learn/go/te2.go:27 +0x107
  18. created by main.main
  19. /home/jon/learn/go/te2.go:45 +0xd3
  20. exit status 2

有什么想法吗?

以下是代码片段:

  1. package main
  2. import "fmt"
  3. import "bufio"
  4. import "os"
  5. import "time"
  6. import "net/http"
  7. var req = []byte("GET /small HTTP/1.1\r\n" +
  8. "Host: localhost\r\n" +
  9. "Content-Length: 0\r\n\r\n")
  10. var buf = make([]byte, 1024)
  11. var total = 0
  12. var t0 = time.Now()
  13. var c = make(chan int)
  14. func httpGet() int {
  15. req, err := http.NewRequest("GET", "http://10.3.0.6/small", nil)
  16. //req.Header.Add("User-Agent", `MYCLIENT`)
  17. //req.Header.Add("Cookie", `sessid=12345`)
  18. client := &http.Client{}
  19. resp, err := client.Do(req)
  20. //defer resp.Body.Close()
  21. if err != nil {
  22. fmt.Println(err)
  23. }
  24. resp.Body.Close()
  25. total++
  26. if total == 10000 {
  27. fmt.Println(time.Now().Sub(t0))
  28. }
  29. c <- 1
  30. return 0
  31. }
  32. func main() {
  33. i := 1
  34. t0 = time.Now()
  35. for i < 1000 {
  36. go httpGet()
  37. i += 1
  38. }
  39. for 1 < 2 {
  40. <-c
  41. go httpGet()
  42. }
  43. reader := bufio.NewReader(os.Stdin)
  44. text, _ := reader.ReadString('\n')
  45. fmt.Println(text)
  46. }
英文:

When running the following http client to stress test a web server, got strange error, wonder what was the cause. The version of go is go1.8.1 linux/amd64 running on Ubuntu 14.04 with 16GB of ram.

  1. $ go run te2.go
  2. 563.904492ms
  3. Get http://10.3.0.6/small: dial tcp 10.3.0.6:80: connect: cannot assign requested address
  4. Get http://10.3.0.6/small: dial tcp 10.3.0.6:80: connect: cannot assign requested address
  5. Get http://10.3.0.6/small: dial tcp 10.3.0.6:80: connect: cannot assign requested address
  6. panic: runtime error: invalid memory address or nil pointer dereference
  7. [signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x5e3b27]
  8. goroutine 140284 [running]:
  9. main.httpGet(0x0)
  10. /home/jon/learn/go/te2.go:27 +0x107
  11. created by main.main
  12. /home/jon/learn/go/te2.go:45 +0xd3
  13. panic: runtime error: invalid memory address or nil pointer dereference
  14. [signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x5e3b27]
  15. goroutine 140375 [running]:
  16. main.httpGet(0x0)
  17. /home/jon/learn/go/te2.go:27 +0x107
  18. created by main.main
  19. /home/jon/learn/go/te2.go:45 +0xd3
  20. exit status 2

any ideas?

Here is the code snippet:

  1. package main
  2. import &quot;fmt&quot;
  3. import &quot;bufio&quot;
  4. import &quot;os&quot;
  5. import &quot;time&quot;
  6. import &quot;net/http&quot;
  7. var req = []byte(&quot;GET /small HTTP/1.1\r\n&quot; +
  8. &quot;Host: localhost\r\n&quot; +
  9. &quot;Content-Length: 0\r\n\r\n&quot;);
  10. var buf = make([]byte, 1024)
  11. var total = 0;
  12. var t0 = time.Now()
  13. var c = make(chan int)
  14. func httpGet () int {
  15. req, err := http.NewRequest(&quot;GET&quot;, &quot;http://10.3.0.6/small&quot;, nil)
  16. //req.Header.Add(&quot;User-Agent&quot;, `MYCLIENT`)
  17. //req.Header.Add(&quot;Cookie&quot;, `sessid=12345`)
  18. client := &amp;http.Client{}
  19. resp, err := client.Do(req)
  20. //defer resp.Body.Close()
  21. if (err != nil) {
  22. fmt.Println(err)
  23. }
  24. resp.Body.Close()
  25. total ++
  26. if (total == 10000) {
  27. fmt.Println(time.Now().Sub(t0))
  28. }
  29. c &lt;- 1
  30. return 0;
  31. }
  32. func main() {
  33. i := 1
  34. t0 = time.Now()
  35. for (i &lt; 1000) {
  36. go httpGet()
  37. i += 1
  38. }
  39. for (1 &lt; 2) {
  40. &lt;-c
  41. go httpGet()
  42. }
  43. reader := bufio.NewReader(os.Stdin)
  44. text, _ := reader.ReadString(&#39;\n&#39;)
  45. fmt.Println(text)
  46. }

答案1

得分: 3

在这个片段中,你正在检查err并继续执行。

所以如果发生了某些事情,err不是nil,但resp(或resp.Body)是nil指针-你会打印错误然后解引用一个空指针。

你应该这样做:如果发生错误-清理并从函数中返回。

英文:
  1. resp, err := client.Do(req)
  2. //defer resp.Body.Close()
  3. if (err != nil) {
  4. fmt.Println(err)
  5. }
  6. resp.Body.Close()

In this fragment you're checking the err and continue execution.

So if something happened and the err is not nil, but resp is (or the resp.Body is) - you print the error then dereference a nil pointer.

What you should have done: if an error occurs - cleanup and return from the function.

huangapple
  • 本文由 发表于 2017年5月8日 11:03:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/43839145.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定