更新、更全的《Go从入门到放弃》的更新网站,更有python、go、人工智能教学等着你:https://www.cnblogs.com/nickchen121/p/11517502.html

Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现。

一、net/http介绍

Go语言内置的net/http包提供了HTTP客户端和服务端的实现。

1.1 HTTP协议

超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。

二、HTTP客户端

2.1 基本的HTTP/HTTPS请求

Get、Head、Post和PostForm函数发出HTTP/HTTPS请求。

resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
url.Values{"key": {"Value"}, "id": {"123"}})

程序在使用完response后必须关闭回复的主体。

resp, err := http.Get("http://example.com/")
if err != nil {
// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...

2.2 GET请求示例

使用net/http包编写一个简单的发送HTTP请求的Client端,代码如下:

package main

import (
"fmt"
"io/ioutil"
"net/http"
) func main() {
resp, err := http.Get("https://www.nickchen121.com/")
if err != nil {
fmt.Println("get failed, err:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("read from resp.Body failed,err:", err)
return
}
fmt.Print(string(body))
}

将上面的代码保存之后编译成可执行文件,执行之后就能在终端打印nickchen121.com网站首页的内容了,我们的浏览器其实就是一个发送和接收HTTP协议数据的客户端,我们平时通过浏览器访问网页其实就是从网站的服务器接收HTTP数据,然后浏览器会按照HTML、CSS等规则将网页渲染展示出来。

2.3 带参数的GET请求示例

关于GET请求的参数需要使用Go语言内置的net/url这个标准库来处理。

func main() {
apiUrl := "http://127.0.0.1:9090/get"
// URL param
data := url.Values{}
data.Set("name", "小王子")
data.Set("age", "18")
u, err := url.ParseRequestURI(apiUrl)
if err != nil {
fmt.Printf("parse url requestUrl failed,err:%v\n", err)
}
u.RawQuery = data.Encode() // URL encode
fmt.Println(u.String())
resp, err := http.Get(u.String())
if err != nil {
fmt.Println("post failed, err:%v\n", err)
return
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("get resp failed,err:%v\n", err)
return
}
fmt.Println(string(b))
}

对应的Server端HandlerFunc如下:

func getHandler(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
data := r.URL.Query()
fmt.Println(data.Get("name"))
fmt.Println(data.Get("age"))
answer := `{"status": "ok"}`
w.Write([]byte(answer))
}

2.4 Post请求示例

上面演示了使用net/http包发送GET请求的示例,发送POST请求的示例代码如下:

package main

import (
"fmt"
"io/ioutil"
"net/http"
"strings"
) // net/http post demo func main() {
url := "http://127.0.0.1:9090/post"
// 表单数据
//contentType := "application/x-www-form-urlencoded"
//data := "name=小王子&age=18"
// json
contentType := "application/json"
data := `{"name":"小王子","age":18}`
resp, err := http.Post(url, contentType, strings.NewReader(data))
if err != nil {
fmt.Println("post failed, err:%v\n", err)
return
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("get resp failed,err:%v\n", err)
return
}
fmt.Println(string(b))
}

对应的Server端HandlerFunc如下:

func postHandler(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
// 1. 请求类型是application/x-www-form-urlencoded时解析form数据
r.ParseForm()
fmt.Println(r.PostForm) // 打印form数据
fmt.Println(r.PostForm.Get("name"), r.PostForm.Get("age"))
// 2. 请求类型是application/json时从r.Body读取数据
b, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Println("read request.Body failed, err:%v\n", err)
return
}
fmt.Println(string(b))
answer := `{"status": "ok"}`
w.Write([]byte(answer))
}

2.5 自定义Client

要管理HTTP客户端的头域、重定向策略和其他设置,创建一个Client:

client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
resp, err := client.Get("http://example.com")
// ...
req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...

2.6 自定义Transport

要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport:

tr := &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: pool},
DisableCompression: true,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")

Client和Transport类型都可以安全的被多个go程同时使用。出于效率考虑,应该一次建立、尽量重用。

三、服务端

3.1 默认的Server

ListenAndServe使用指定的监听地址和处理器启动一个HTTP服务端。处理器参数通常是nil,这表示采用包变量DefaultServeMux作为处理器。

Handle和HandleFunc函数可以向DefaultServeMux添加处理器。

http.Handle("/foo", fooHandler)
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(":8080", nil))

3.2 默认的Server示例

使用Go语言中的net/http包来编写一个简单的接收HTTP请求的Server端示例,net/http包是对net包的进一步封装,专门用来处理HTTP协议的数据。具体的代码如下:

// http server

func sayHello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello 沙河!")
} func main() {
http.HandleFunc("/", sayHello)
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Printf("http server failed, err:%v\n", err)
return
}
}

将上面的代码编译之后执行,打开你电脑上的浏览器在地址栏输入127.0.0.1:9090回车,此时就能够看到如下页面了。

3.3 自定义Server

要管理服务端的行为,可以创建一个自定义的Server:

s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())

Go语言标准库之net_http的更多相关文章

  1. 附录二 C语言标准库

    上章回顾 数组和指针相同与不同 通过指针访问数组和通过数组访问指针 指针在什么时候可以加减运算 函数指针的申明和调用 函数数组和数组函数 git@github.com:Kevin-Dfg/Data-S ...

  2. Go语言标准库_输入/输出

    Go语言标准库_输入/输出 转载节选自<Go语言标准库> Reader 接口 type Reader interface { Read(p []byte) (n int, err erro ...

  3. GO语言标准库—命令行参数解析FLAG

    flag包是Go语言标准库提供用来解析命令行参数的包,使得开发命令行工具更为简单 常用方法 1.flag.Usage 输出使用方法,如linux下ls -h的帮助输出 2.flag.Type(参数名, ...

  4. Go语言标准库之JSON编解码

    Go语言标准库之JSON编解码 基本的类型 Go语言中的数据类型和JSON的数据类型的关系 bool -> JSON boolean float64 -> JSON numbers str ...

  5. Go语言标准库之time

    Go语言标准库之time 时间的格式化和解析 格式化 Format Go语言和其他语言的时间格式化的方式不同,Go语言格式化的方式更直观,其他的语言一般是yyyy-mm-dd package main ...

  6. C语言标准库之setjmp

    协程的介绍 协程(coroutine),意思就是“协作的例程”(co-operative routines),最早由Melvin Conway在1963年提出并实现.跟主流程序语言中的线程不一样,线程 ...

  7. C语言标准库 qsort bsearch 源码实现

    C语言是简洁的强大的,当然也有很多坑.C语言也是有点业界良心的,至少它实现了2个最最常用的算法:快速排序和二分查找. 我们知道,对于C语言标准库 qsort和 bsearch: a. 它是“泛型”的, ...

  8. Go语言标准库flag基本使用

    文章引用自   Go语言标准库flag基本使用 os.Args 如果你只是简单的想要获取命令行参数,可以像下面的代码示例一样使用os.Args来获取命令行参数. package main import ...

  9. Go语言标准库log介绍

    Go语言标准库log介绍 无论是软件开发的调试阶段还是软件上线之后的运行阶段,日志一直都是非常重要的一个环节,我们也应该养成在程序中记录日志的好习惯. log Go语言内置的log包实现了简单的日志服 ...

随机推荐

  1. C++实现多组数据合并输出

    思路 假设有多组数据,每一组都是按从小到大的顺序输入的,设计如下数据结构 前面一列是每一组数据的首部,后面是真正的数据,首部的定义为: struct head { Node* next; head* ...

  2. 使用CefSharp在.NET中嵌入Chromium

    使用CefSharp可以在.NET轻松的嵌入Html,不用担心WPF与Winform 控件与它的兼容性问题,CefSharp大部分的代码是C#,它可以在VB或者其他.NET平台语言中来进行使用. 近几 ...

  3. .net软件开发脚本规范-SQL脚本标准

    一. SQL脚本标准 各文件夹存放的脚本说明 存储过程:除“基础_”开头的所有存储过程,包含新增.修改.删除.列表.提交.审核. 基础数据:“基础_”开头的存储过程,用于下拉列表的数据加载公共方法. ...

  4. 解放双手——相机与IMU外参的在线标定

    本文作者 沈玥伶,公众号:计算机视觉life,编辑部成员 一.相机与IMU的融合 在SLAM的众多传感器解决方案中,相机与IMU的融合被认为具有很大的潜力实现低成本且高精度的定位与建图.这是因为这两个 ...

  5. mybatis 源码分析(二)mapper 初始化

    mybatis 的初始化还是相对比较复杂,但是作者在初始化过程中使用了多种设计模式,包括建造者.动态代理.策略.外观等,使得代码的逻辑仍然非常清晰,这一点非常值得我们学习: 一.mapper 初始化主 ...

  6. Guava 常用工具类

    引入guava包: <dependency> <groupId>com.google.guava</groupId> <artifactId>guava ...

  7. 图表控件业界革命 -Arction新产品LightningChart JS 上市

    芬兰高科技企业Arction Ltd 在今年8月份推出了用于网页的数据可视化控件新解决方案—— LightningChart JS. 初次的基准测试表明,该产品为网页应用程序的数据可视化刷新了新的纪录 ...

  8. C#ORM中的对象映射

    使用Linq.Expressions来动态生成映射方法 1.我们先写个简单的类Test,包含一个ID和Name. public class Test { public int? ID { get; s ...

  9. vux-scroller实现移动端上拉加载功能

    本文将讲述vue-cli+vux-scroller实现移动端的上拉加载功能: 纠错声明:网上查阅资料看到很多人都将vux和vuex弄混,在这里我们先解释一下,vuex是vue框架自带的组件,是数据状态 ...

  10. Java 最全异常讲解

    1. 导引问题 实际工作中,遇到的情况不可能是非常完美的.比如:你写的某个模块,用户输入不一定符合你的要求.你的程序要打开某个文件,这个文件可能不存在或者文件格式不对,你要读取数据库的数据,数据可能是 ...