简介
net/http 包为Golang官方的http包,可以用于实现http客户端和服务端;虽然实际项目过程中用resty更加的方便,但是通过对net/http的使用和抓包分析,可以更好的理解HTTP协议实现的原理。
示例
服务端
- 监听8090端口。
- 实现/hello接口。
golang
package main
import (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "hello\n")
}
func main() {
http.HandleFunc("/hello", hello)
http.ListenAndServe(":8090", nil)
}
客户端
- 连续进行三次HTTP请求。
- 打印HTTP响应状态码和Body。
golang
package main
import (
"fmt"
"time"
"io"
"net/http"
)
func hello() {
resp, err := http.Get("http://127.0.0.1:8090/hello")
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response status:", resp.Status)
bs, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("http get err : ", err)
return
}
fmt.Println("body: ", string(bs))
}
func main() {
for i:=0; i < 3; i++ {
go func() {
hello()
}()
}
time.Sleep(600*time.Second)
}
抓包分析
tcpdump -i lo port 8090 -envv -w http.pcap
- 在客户端连续发起三次HTTP请求后,netstat 命令可以查看到有两个连接是ESTABLISHED ,一个连接是TIME_WAIT,在等待足够的时间后恢复到初始状态,即连接都被释放。
bash
[xiaofeng@localhost gostudy]$ netstat -antu|grep 8090
tcp6 0 0 :::8090 :::* LISTEN
[xiaofeng@localhost gostudy]$
[xiaofeng@localhost gostudy]$
[xiaofeng@localhost gostudy]$ netstat -antu|grep 8090
tcp 0 0 127.0.0.1:48836 127.0.0.1:8090 ESTABLISHED
tcp 0 0 127.0.0.1:48834 127.0.0.1:8090 ESTABLISHED
tcp 0 0 127.0.0.1:48838 127.0.0.1:8090 TIME_WAIT
tcp6 0 0 :::8090 :::* LISTEN
tcp6 0 0 127.0.0.1:8090 127.0.0.1:48834 ESTABLISHED
tcp6 0 0 127.0.0.1:8090 127.0.0.1:48836 ESTABLISHED
[xiaofeng@localhost gostudy]$ netstat -antu|grep 8090
tcp6 0 0 :::8090 :::* LISTEN
- 抓包分析
- wireshark追踪第一条HTTP流如下,可以推断出为ESTABLISHED中源端口48834的连接。
- TCP三次握手建立连接
- HTTP GET请求
- HTTP响应hello
- Keep-Alive保持连接
- TCP四次挥手断开连接
- wireshark追踪第二条HTTP流如下,可以推断出为ESTABLISHED中源端口48836的连接。
- TCP三次握手建立连接
- HTTP GET请求
- HTTP响应hello
- Keep-Alive保持连接
- TCP四次挥手断开连接
- wireshark追踪第三条HTTP流如下,可以推断出为TIME_WAIT中源端口48838的连接。
- TCP三次握手建立连接
- HTTP GET请求
- HTTP响应hello
- TCP四次挥手断开连接
总结
- 可以通过示例代码了解net/http最基本的用法。
- 可以通过抓包分析了解http协议交互过程和协议字段。
- 可以通过Keep-Alive了解到每个主机默认最大空闲连接数为2(DefaultMaxIdleConnsPerHost)。