19 Go网络编程(二):HTTP服务及HTTP客户端
2019-07-06 本文已影响22人
GoFuncChan
一、HTTP概述
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。一个HTTP"客户端"是一个应用程序(Web浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个HTTP的请求的目的。一个HTTP"服务器"同样也是一个应用程序(通常是一个Web服务,如Apache Web服务器或IIS服务器等),通过接收客户端的请求并向客户端发送HTTP响应数据。HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
HTTP 请求报文结构
HTTP请求报文结构.pngHTTP 响应报文信息
HTTP响应报文信息.jpg二、Go 搭建HTTP服务器
1.基于HTTP的Web服务
大多数编程语言都支持web服务器的开发,市面上也有许多针对web服务的解决方案,如PHP的LANMP方案,JAVA的Tomcat等,其开发web服务系统通常都需要搭建一堆核心构建和周边设施。Go对基于http的web开发非常友好,仅适用其标准的net/http包你就可以构建自己的web服务,且其并发能力似乎天生就为web而准备。
这里有非常全面的net/http中文翻译,该包是go开发web服务的核心包,应深入了解以下。
2.编写一个简单的HTTP服务端
步骤:
- 编写针对特定需求的处理器并为其设置访问路径;
- http.ListenAndServe("{ip}:{port}", nil)就可启动一个监听服务;
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
//搭建基本的http服务器 http_server.go
func main() {
//设置http服务处理函数1
http.HandleFunc("/jianshu", func(writer http.ResponseWriter, request *http.Request) {
//这里使用一个http客户端方法获取jianshu首页数据
response, err := http.Get("http://www.jianshu.com")
SErrorFunc(err, "http.Get")
bytes, err := ioutil.ReadAll(response.Body)
SErrorFunc(err, "ioutil.ReadAll")
writer.Write(bytes)
})
//设置http服务处理函数2
http.HandleFunc("/hi", func(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte("Hi Gopher!!!"))
})
//设置http服务处理函数3:直接绑定函数
http.HandleFunc("/showrequest", ShowRequest)
//服务绑定端口并启动服务
http.ListenAndServe("0.0.0.0:8888", nil)
fmt.Println("服务端已启动....监听端口:8888")
}
func ShowRequest(writer http.ResponseWriter, request *http.Request) {
req, err := ioutil.ReadAll(request.Body)
SErrorFunc(err, "ioutil.ReadAll")
writer.Write([]byte("请求Method:" + request.Method))
writer.Write([]byte("请求Host:" + request.Host))
writer.Write([]byte("请求客户端地址:" + request.RemoteAddr))
writer.Write([]byte("请求链接:" + request.RequestURI))
writer.Write([]byte("请求主机:" + request.Host))
writer.Write([]byte("请求头:" + request.Header.Get("")))
writer.Write(req)
}
//生成可执行文件
go build http_server.go
//运行可执行文件即可启动http监听服务
如示例中设置了三个web处理器,在浏览器键入:
就可看到本地web服务
三、HTTP 客户端
Go的net/http网络包提供了HTTP客户端的封装方法,直接使用http的标准方法向网络发起请求,许多爬虫程序都是基于http客户端实现,这里做一个常用的GET和POST方法演示
编写一个HTTP客户端:
//基本的httpclient请求
/*
·发起百度搜索的GET请求:"http://www.baidu.com/s?wd=简书",打印回复的内容
·对https://httpbin.org/post发起post请求,携带表单数据,键值自拟,打印回复的内容
·表单数据类型 application/x-www-form-urlencoded,表单读取API:strings.NewReader("rmb=0.5&hobby=接客和约汉"))
*/
func BaseHttpClient() {
//1. http.Get请求
resp1, err := http.Get("http://www.baidu.com/s?wd=简书")
MErrorHandler(err, "http.Get")
defer resp1.Body.Close()
bytes1, err := ioutil.ReadAll(resp1.Body)
MErrorHandler(err, "ioutil.ReadAll")
fmt.Printf("这是响应头:%s\n", resp1.Header)
fmt.Printf("这是响应体:%s\n", string(bytes1))
//2. http.Post请求
resp2, err := http.Post("https://httpbin.org/post", "application/x-www-form-urlencoded", strings.NewReader("name=fun&age=18&desc=developer"))
CErrorFunc(err, "http.Post")
defer resp2.Body.Close()
bytes2, err := ioutil.ReadAll(resp2.Body)
CErrorFunc(err, "ioutil.ReadAll")
fmt.Printf("Post请求响应体:%s\n", string(bytes2))
}
func MErrorHandler(err error, where string) {
if err != nil {
fmt.Println("此处有错:", err)
os.Exit(1)
}
}