1. HTTP协议
TCP/IP协议栈由上至下分为以下四层:
- 应用层:为用户提供应用服务时的通信活动
- DNS、FTP(文件传输)、HTTP(超文本传输)
- 传输层:网络中两台计算机之间的数据传输
- TCP、UDP、SPX
- 网络层:网络中相邻节点之间的数据帧传送
- IP、IPX
- 链路层:构成网络传输介质的各种基础设施
- 以太网、ADSL、TD-LTE
通过协议栈传输数据包的过程,本质上就是不断封装与解封在的过程。
发送数据时,应用层组织处HTTTP数据,由传输层封装TCP首部,网络层封装IP首部,链路层封装以太网首部,以以太网包的形式在网内传输;
接收数据时,将接收到的以太网包在链路层解析其以太网首部,其余部分传递给网络层解析IP首部,传递给传输层解析TCP首部,最后得到HTTP数据传递给应用层。
作为TCP/IP协议的一部分,HTTP协议工作在协议栈的最高层——应用层,负责为用户提供针对超文本数据的网络应用,如:
- Apache、Nginx、IIS、各种浏览器,等等
借助curl可以了解客户端发送给服务器的HTTP请求。
- curl -v "https://ifconfig.io/ip"
- GET /ip HTTP/2 // 请求类型 访问路径 协议
- Host: ifconfig.io // 主机域名
- User-Agent: curl/7.63.0 // 客户端信息
- Accept: */* // 期望接收的内容类型
Go语言的HTTP客户端功能齐备,在最基本的情况下,它为各种选项提供了合理的默认设置,让开发者可以无需关心底层,同时也提供了细粒度的控制。
2. GET请求
通过Go语言标准库net/http包的Get函数,可以直接向服务器发送GET请求
- GET请求用于从服务器获取数据
- 对于从服务器获取一些数据而言,使用默认参数配置的客户端和请求头,完全够用
- 例如:客户端可以通过向https://ifconfig.io/ip发送GET请求,来获取自己的IP地址
- response, err := http.Get("https://ifconfig.io/ip")
- resBody, err := ioutil.ReadAll(response.Body)
- fmt.Printf("%s", resBody) // 124.207.192.18
// 发送简单的GET请求
// 标准库的net/http包提供了一个快捷的方法,可用于发送简单的GET请求
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
response, err := http.Get(
"https://ifconfig.io/ip")
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
resBody, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", resBody)
}
// 打印输出:
xxx.xxx.xxx.xxx ip地址
3. POST请求
通过Go语言标准库net/http包的Post函数,可以直接向服务器发送Post请求。
- POST请求用于向服务器提交数据。
- 调用Post函数除了需要指定访问路径,还需要提供被提交的数据及其内容类型。
- 例如:客户端可以通过向https://httpbin.org/post发送POST请求,来获取自己的信息
- postData := strings.NewReader(`{"some": "json"}`)// 构建基于字符串的输入流
- response, err := http.Post("https://httpbin.org/post", "application/json", postData)// 参数解析:访问路径,数据格式,输入流
- resBody, err := ioutil.ReadAll(response.Body)
- fmt.Printf("%s", resBody) // %s将字节切片转化为字符串来打印
// 发送简单的POST请求
// 标准库的net/http包提供了一个快捷
// 的方法,可用于发送简单的POST请求
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"
)
func main() {
postData := strings.NewReader(
`{"some": "json"}`)
response, err := http.Post(
"https://httpbin.org/post",
"application/json", postData)
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
resBody, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", resBody)
}
https://httpbin.org是一个用于测试HTTP客户端的工具,向/post路径发送POST请求,服务器将返回客户端发送给它的数据及一些客户端相关信息。
// 返回的信息:
{
"args": {},
"data": "{\"some\": \"json\"}",
"files": {},
"form": {},
"headers": {
"Accept-Encoding": "gzip",
"Content-Length": "16",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "Go-http-client/2.0",
"X-Amzn-Trace-Id": "Root=1-5e3fb89c-66cc30b444d9340656de5fbc"
},
"json": {
"some": "json"
},
"origin": "xxx.xxx.xxx.xxx", // 客户端ip,已隐去
"url": "https://httpbin.org/post"
}