net/http包提供了HTTP客户端和服务端的实现。
http.HandleFunc-注册回调函数
func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
HandleFunc注册一个处理器函数handler和对应的模式pattern(注册到DefaultServeMux)。ServeMux的文档解释了模式的匹配机制。
http.ListenAndServe
func ListenAndServe(addr string, handler Handler) error
ListenAndServe监听TCP地址addr,并且会使用handler参数调用Serve函数处理接收到的连接。handler参数一般会设为nil,此时会使用DefaultServeMux。
HTTP服务器
服务端示例代码:
package main
import (
"fmt"
"net/http"
)
func main(){
//注册回调函数
http.HandleFunc("/hello", handler)
//绑定tcp监听地址,并开始接受请求,然后调用服务端处理程序来处理传入的连接请求。
//params:第一个参数 addr 即监听地址;第二个参数表示服务端处理程序,通常为nil
//当参2为nil时,服务端调用 http.DefaultServeMux 进行处理
http.ListenAndServe("127.0.0.1:8080", nil)
}
func handler (w http.ResponseWriter, r *http.Request){
fmt.Println("method = ", r.Method) //请求方法
fmt.Println("URL = ", r.URL) // 浏览器发送请求文件路径
fmt.Println("header = ", r.Header) // 请求头
fmt.Println("body = ", r.Body) // 请求包体
fmt.Println(r.RemoteAddr, "连接成功") //客户端网络地址
w.Write([]byte("hello http server"))
}
Output:
浏览器输入url地址:127.0.0.1:8080/hello
func myHandler(w http.ResponseWriter, r * http.Request) 有两个参数:
w http.ResponseWriter 和 r *http.Request。
w用来“给客户端回发数据”。它是一个interface:
type ResponseWriter interface {
Header()
HeaderWrite([]byte) (int, error)
WriteHeader(int)
}
r 用来“接收客户端发送的数据”。浏览器发送给服务器的http请求包的内容可以借助r来查看。它对应一个结构体:
type Request struct {
Method string // 浏览器请求方法 GET、POST…
URL *url.URL // 浏览器请求的访问路径
……
Header Header // 请求头部
Body io.ReadCloser // 请求包体
RemoteAddr string // 浏览器地址
……
ctx context.Context
}
HTTP客户端
客户端访问web服务器数据,主要使用func Get(url string) (resp *Response, err error)函数来完成。读到的响应报文数据被保存在 Response 结构体中。
type Response struct {
Status string // e.g. "200 OK"
StatusCode int // e.g. 200
Proto string // e.g. "HTTP/1.0"
……
Header Header
Body io.ReadCloser
……
}
服务器发送的响应包体被保存在Body中。可以使用它提供的Read方法来获取数据内容。保存至切片缓冲区中,拼接成一个完整的字符串来查看。
结束的时候,需要调用Body中的Close()方法关闭io。
示例代码:
package main
import(
"fmt"
"net/http"
)
func main(){
// 使用Get方法获取服务器响应包数据
resp, err := http.Get("http://127.0.0.1:3466/hello")
if err != nil {
fmt.Println("Get err:", err)
return
}
defer resp.Body.Close()
// 获取服务器端读到的数据
fmt.Println("Status = ", resp.Status) // 状态
fmt.Println("StatusCode = ", resp.StatusCode) // 状态码
fmt.Println("Header = ", resp.Header) // 响应头部
fmt.Println("Body = ", resp.Body) // 响应包体
//读取body内的内容
content, err := ioutil.ReadAll(resp.Body)
// 打印从body中读到的所有内容
fmt.Println("result = ", string(content))
}
Output:
智一面王老师说运维推荐初级Golang开发工程师在线评测:http://www.gtalent.cn/exam/interview/FM2N7xj54dQBPfUE