golang|九、Golang网络编程(Go HTTP客户端服务器学习与开发)

【golang|九、Golang网络编程(Go HTTP客户端服务器学习与开发)】
文章目录

      • web工作方式:
      • http和URL:
      • http请求包:
      • http应答包测试:
      • http应答包格式:
      • http WEB服务器:
      • WEB服务器练习:将本地文件写到浏览器
      • http WEB客户端:

web工作方式:
1. 客户端 ——> 访问 www.baidu.com——> DNS 服务器。 返回 该域名对应的 IP地址。2. 客户端 ——> IP + port ——> 访问 网页数据。(TCP 连接。 HTTP协议。)

http和URL:
http 超文本传输协议。规定了 浏览器访问 Web服务器 进行数据通信的规则。http(明文) -- TLS、SSL -- https(加密)URL:统一资源定位。 在网络环境中唯一定位一个资源数据。浏览器地址栏内容。

http请求包:
请求行:请求方法(空格)请求文件URL(空格)协议版本(\r\n) GET、POST请求头:语法格式 : key :value空行:\r\n—— 代表 http请求头结束。请求包体:请求方法对应的数据内容。 GET方法没有内容!!

http应答包测试:
1. 使用 net/http包 创建 web 服务器 1) 注册回调函数。http.HandleFunc("/itcast", handler)参1:用户访问文件位置参2:回调函数名 —— 函数必须是 (w http.ResponseWriter, r *http.Request) 作为参数。 2)绑定服务器监听地址。http.ListenAndServe("127.0.0.1:8000", nil) 2. 回调函数: 本质:函数指针。通过地址,在某一特定位置,调用函数。 在程序中,定义一个函数,但不显示调用。当某一条件满足时,该函数由操作系统自动调用。

http应答包格式:
状态行:协议版本号(空格)状态码(空格)状态码描述(\r\n)响应头:语法格式 : key :value空行:\r\n响应包体: 请求内容存在: 返回请求页面内容请求内容不存在: 返回错误页面描述。

http WEB服务器:
1.注册回调函数:http.HandleFunc("/", myHandler) func myHandler(w http.ResponseWriter, r *http.Request)w:给客户端回发数据r:从客户端读到的数据 type ResponseWriter interface {Header() Header Write([]byte) (int, error) WriteHeader(int) } type Request struct {Method string// 浏览器请求方法 GET、POST… URL *url.URL// 浏览器请求的访问路径 …… Header Header// 请求头部 Body io.ReadCloser // 请求包体 RemoteAddr string // 浏览器地址 …… ctx context.Context }2. 绑定服务器地址结构:http.ListenAndServe("127.0.0.1:8000", nil) 参2:通常传 ni 。 表示让服务端 调用默认的 http.DefaultServeMux 进行处理

package mainimport ( "net/http" "fmt" )func myHandle(w http.ResponseWriter, r *http.Request) { // w : 写给客户端的数据内容 w.Write([]byte("this is a Web server")) // r: 从客户端读到的内容 fmt.Println("Header:", r.Header) fmt.Println("URL:", r.URL) fmt.Println("Method:", r.Method) fmt.Println("Host:", r.Host) fmt.Println("RemoteAddr:", r.RemoteAddr) fmt.Println("Body:", r.Body) }func main(){ // 注册回调函数, 该函数在客户端访问服务器时,会自动被调用 //http.HandleFunc("/itcast", myHandle) http.HandleFunc("/", myHandle) // 绑定服务器监听地址 http.ListenAndServe("127.0.0.1:8000", nil) }

WEB服务器练习:将本地文件写到浏览器
package mainimport ( "net/http" "fmt" "os" )func OpenSendFile(fNmae string, w http.ResponseWriter){ pathFileName := "C:/itcast/test" + fNmae f, err := os.Open(pathFileName) if err != nil {fmt.Println("Open err:", err) w.Write([]byte(" No such file or directory !")) return } defer f.Close() buf := make([]byte, 4096) for {n, _ := f.Read(buf)// 从本地将文件内容读取。 if n == 0 {return } w.Write(buf[:n])// 写到 客户端(浏览器)上 } }func myHandler(w http.ResponseWriter, r *http.Request) { fmt.Println("客户端请求:", r.URL) OpenSendFile(r.URL.String(), w) }func main(){ // 注册回调函数 http.HandleFunc("/", myHandler) // 绑定监听地址 http.ListenAndServe("127.0.0.1:8000", nil) }

http WEB客户端:
1. 获取web服务器数据: func Get(url string) (resp *Response, err error) 返回:http应答包,保存成 struct type Response struct {Statusstring // e.g. "200 OK" StatusCode int// e.g.200 Protostring // e.g. "HTTP/1.0" …… Header Header Body io.ReadCloser …… } 2. defer resp.Body.Close()3. for 循环提取 Body 数据: n, err := resp.Body.Read(buf) if n == 0 {fmt.Println("--Read finish!") break } if err != nil && err != io.EOF {fmt.Println("resp.Body.Read err:", err) return }

package mainimport ( "net/http" "fmt" "io" )func main(){ // 使用Get方法获取服务器响应包数据 //resp, err := http.Get("http://www.baidu.com") resp, err := http.Get("http://127.0.0.1:8000/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)// 响应包体 buf := make([]byte, 4096)// 定义切片缓冲区,存读到的内容 var result string // 获取服务器发送的数据包内容 for {n, err := resp.Body.Read(buf)// 读body中的内容。 if n == 0 {fmt.Println("--Read finish!") break } if err != nil && err != io.EOF {fmt.Println("resp.Body.Read err:", err) return }result += string(buf[:n])// 累加读到的数据内容 } // 打印从body中读到的所有内容 fmt.Println("result = ", result) }

    推荐阅读