go语言 http学习
net/http库学习
概念
处理器
- 处理器:拥有ServeHTTP方法的接口(任何类型)
签名:ServeHTTP(http.ResponseWriter, *http.Request)
- ResponseWriter接口
- 指向Request结构的指针
- ServeMux结构(拥有ServeHTTP方法,如上签名)
- Handler结构
- 多路复用器 DefaultServeMux(ServeMux结构的实例)
处理器函数
- 与处理器有相同行为的函数
- 与ServeHTTP方法有相同的签名
ServeMux
- HTTP请求多路复用器
- 接收HTTP请求__并根据请求中的__URL__将请求重定向到正确的__处理器
- ServeMux结构也实现了ServeHTTP方法,它也是一个处理器
- ServeMux的ServeHTTP方法,调用与被请求URL相对应的__处理器__的ServeHTTP方法
最简单的Web服务器
import "fmt"
import "net/http"
// 处理器
type HelloHandler struct{}
func ( h *HelloHandler) ServeHTTP ( w http.ResponseWriter, r * http.Request){
fmt.Fprintf( w, "Hello" )
}
// 处理器函数
func hello( w http.ResponseWriter, r * http.Request){
fmt.Fprintf( w, "Hello" )
}
func main () {
server := http.Server{
Addr: "127.0.0.1:8080",
//Handler: nil, //可以指定处理器
}
fmt.Println("hello https://tool.lu/")
//http.ListenAndServe(":8181", nil)
//server.ListenAndServe()
// 将 处理器 绑定到DefaultServeMux
// Handle是ServeMux结构的方法,而DefaultServeMux是ServeMux的实例
//hello := HelloHandler{}
//http.Handle("/hello", &hello)
// 将函数转换为处理器,再将处理器绑定到DefaultServeMux
//http.HandleFunc( "/hello", hello )
//使用默认的多路复用器DefaultServeMux作为处理器
server.ListenAndServeTLS("cert.pem", "key.pem")
}
http客户端
http.NewRequest
- htp.Client -> http.request(http.NewRequest) -> client.Do(request)
- NewRequest(method, urlStr string, body io.Reader)
- 第三个参数是请求的body中的内容
- request.Header.Set
- 向请求首部添加信息
http.Clinet
- cient结构api
- client.get/post/postform
- client参数配置
- Transport RoundTripper
- CheckRedirect func(req Request, via []Request) error
- Jar CookieJar
- Timeout time.Duration
- Transport
- 为了控制代理、安全套接层设置、保持连接、压缩、超时设置和其它设定,需要创建一个Transport
- MaxIdleConns
- 对所有host的最大连接数量
- MaxIdleConnsPerHost
- 对__每个host__的最大连接数量
tr := &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: pool},
DisableCompression: true,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")
tr := &http.Transport{
MaxIdleConnsPerHost: 1000, //是否表示最多建立1000个连接?
}
client := &http.Client{
Transport: tr,
}
http
- http.Get/Post/Postform
resp.Body.Close()
- 当客户端使用完response body后必须使用close对其进行关闭
httplib学习
https://github.com/astaxie/beego
概念
- httplib库主要用来模拟客户端发送HTTP请求
- 类似于curl工具
使用
- request对象
- debug输出
- 设置clinet的TLS信息
gin学习
package tests
import (
"encoding/json"
"fmt"
"github.com/astaxie/beego/httplib"
"github.com/gin-gonic/gin"
"io/ioutil"
"log"
"net/http"
"strings"
"testing"
"time"
)
func handleTestGet(c *gin.Context) {
c.String(http.StatusOK, "test get OK")
}
func handleTestPost(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"code": 1, "message": "test post OK"})
}
func handleParam(c *gin.Context) {
name := c.Param("name")
passwd := c.Param("passwd")
c.String(http.StatusOK, "name: %s, passwd: %s", name, passwd)
}
func handleQuery(c *gin.Context) {
name := c.Query("name")
passwd := c.Query("passwd")
c.String(http.StatusOK, "name: %s, passwd: %s", name, passwd)
}
func handleHTTPLib(c *gin.Context) {
c.IndentedJSON(200, gin.H{"code": 1, "data": "ok"})
}
func runtBasicGinServer() {
fmt.Print("aa")
router := gin.Default()
router.GET("/test_get", handleTestGet)
router.POST("/test_post", handleTestPost)
router.GET("/test_param/:name/*passwd", handleParam)
router.GET("/test_query", handleQuery)
router.GET("/test_httplib", handleHTTPLib)
group := router.Group("/v1")
group.GET("/test_group", handleTestGet)
router.Run(":6543")
}
func printGetResp(resp *http.Response) {
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("read body err %s\n", err.Error())
}
log.Printf("resp body is: %+v\n", string(bodyBytes))
}
func printPostResp(resp *http.Response) {
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("read body err %s\n", err.Error())
}
type body struct {
Code int `json:"code"`
Message string `json:"message"`
}
respBody := body{}
err = json.Unmarshal(bodyBytes, &respBody)
if err != nil {
log.Printf("unmarshal body err %s\n", err.Error())
}
log.Printf("resp body is: %+v\n", respBody)
}
func TestBasicClient(t *testing.T) {
go runtBasicGinServer()
time.Sleep(time.Second * 5)
resp, err := http.Get("http://127.0.0.1:6543/test_get")
if err != nil {
log.Printf("get resp err %s\n", err.Error())
}
printGetResp(resp)
resp, err = http.Post("http://127.0.0.1:6543/test_post", "", strings.NewReader(""))
if err != nil {
log.Printf("get resp err %s\n", err.Error())
}
printPostResp(resp)
resp, err = http.Get("http://127.0.0.1:6543/test_param/name=Bob/passwd=1234")
if err != nil {
log.Printf("get resp err %s\n", err.Error())
}
printGetResp(resp)
resp, err = http.Get("http://127.0.0.1:6543/test_param/name=Bob/")
if err != nil {
log.Printf("get resp err %s\n", err.Error())
}
printGetResp(resp)
resp, err = http.Get("http://127.0.0.1:6543/test_param/name=Bob")
if err != nil {
log.Printf("get resp err %s\n", err.Error())
}
printGetResp(resp)
resp, err = http.Get("http://127.0.0.1:6543/test_query?name=Alice&passwd=123")
if err != nil {
log.Printf("get resp err %s\n", err.Error())
}
printGetResp(resp)
resp, err = http.Get("http://127.0.0.1:6543/v1/test_group")
if err != nil {
log.Printf("get resp err %s\n", err.Error())
}
printGetResp(resp)
res := struct {
Code int `json:"code"`
Message string `json:"message"`
}{}
if err := httplib.Get("http://127.0.0.1:6543/test_httplib").ToJSON(&res); err != nil {
log.Println(err.Error())
}
log.Printf("%+v", res)
}
func TestReuseHTTPLink(t *testing.T) {
go runtBasicGinServer()
time.Sleep(time.Second * 5)
tr := &http.Transport{
MaxIdleConnsPerHost: 100,
MaxIdleConns: 100,
}
c := http.Client{Transport: tr}
url := "http://127.0.0.1:6543/test_get"
/*
连接数,
当前 无剩余 可用连接时 会创建;
当前 有剩余 可用连接则 不创建
*/
// use channel to control http port numbers
ch := make(chan struct{}, 100)
for i := 0; i < 5000; i++ {
go func(i int) {
ch <- struct{}{}
defer func() {
<-ch
}()
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Printf("get req error %s", err.Error())
}
resp, err := c.Do(req)
if err != nil {
log.Printf("do req error %s", err.Error())
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("read body error %s", err.Error())
}
log.Printf("%d body: %s", i, string(bodyBytes))
}(i)
//time.Sleep(time.Microsecond * 50)
//time.Sleep(time.Microsecond * 50)
}
time.Sleep(time.Second * 10)
}
func TestSeqDo(t *testing.T) {
go runtBasicGinServer()
time.Sleep(time.Second * 5)
c := http.Client{}
url := "http://127.0.0.1:6543/test_get"
/*
defaul reuse http link
there is one link to 6543
*/
for i := 0; i < 5000; i++ {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Printf("get req error %s", err.Error())
}
resp, err := c.Do(req)
if err != nil {
log.Printf("do req error %s", err.Error())
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("read body error %s", err.Error())
}
log.Printf("%d body: %s", i, string(bodyBytes))
}
time.Sleep(time.Second * 10)
}
func TestSeqHTTPLib(t *testing.T) {
go runtBasicGinServer()
time.Sleep(time.Second * 5)
url := "http://127.0.0.1:6543/test_get"
/*
???netstat -anp | grep 6543 | grep ESTABLISHED
*/
for i := 0; i < 5000; i++ {
bodyString, err := httplib.Get(url).String()
if err != nil {
log.Printf("httplib get error %s", err.Error())
}
log.Printf("%d body: %s", i, bodyString)
}
time.Sleep(time.Second * 10)
}
binding学习
github.com/gin-gonic/gin/binding
HTTPS服务
参考文献
《Go Web 编程》
Go语言_HTTP包
深入Go语言网络库的基础实现
golang中发送http请求的几种常见情况
Go语言net/http 解读
go net/http Client使用——长连接客户端的使用
https://github.com/astaxie/beego
beego中文文档
go语言 http学习的更多相关文章
- C语言课程学习的总结
C语言课程学习的总结 学习C程序这门课一年了,这是我们学的第一门专业课.在大学里,C语言不但是计算机专业的必修课程而且也是非计算机专业学习计算机基础的一门必修课程.所以作为我这个计算机专业的学生来说当 ...
- [转]C语言指针学习经验总结浅谈
指针是C语言的难点和重点,但指针也是C语言的灵魂 . 这篇C语言指针学习经验总结主要是我入职以来学习C指针过程中的点滴记录.文档里面就不重复书上说得很清楚的概念性东西,只把一些说得不清楚或理解起来比较 ...
- C语言(函数)学习之strstr strcasestr
C语言(函数)学习之[strstr]&[strcasestr]一.strstr函数使用[1]函数原型char*strstr(constchar*haystack,constchar*needl ...
- 【Go语言】学习资料
这段时间一直在看Go语言,6月3日Apple发布了swift发现里面竟然也有许多Go语言的影子,截至现在每天都在感觉到Go语言的强大.确实值得一学 今天在这里给园友们推荐一些Go语言的学习资料 网站 ...
- 远离go path,弃用go get,使用go mod 进行go语言的学习
标题说的是go语言的学习,因为我也没做过开发 文章要解决的仅仅是一个问题 当你使用go get 无论如何get不到所需的包的问题 第一步就是下载goland 新手极其推荐goland,因为直接使用gl ...
- Dart语言快速学习上手(新手上路)
Dart语言快速学习上手(新手上路) // 声明返回值 int add(int a, int b) { return a + b; } // 不声明返回值 add2(int a, int b) { r ...
- D02-R语言基础学习
R语言基础学习——D02 20190423内容纲要: 1.前言 2.向量操作 (1)常规操作 (2)不定长向量计算 (3)序列 (4)向量的删除与保留 3.列表详解 (1)列表的索引 (2)列表得元素 ...
- D01-R语言基础学习
R语言基础学习——D01 20190410内容纲要: 1.R的下载与安装 2.R包的安装与使用方法 (1)查看已安装的包 (2)查看是否安装过包 (3)安装包 (4)更新包 3.结果的重用 4.R处理 ...
- C++语言的学习环境
一.Mac C++语言的学习环境 1. 1.1.C语言 :终端->bash-vi/vim文本编辑器->GNU->GCC文件编译器->a.out可执行文件 1.2.C++语言:终 ...
- 获奖感言和C语言的学习心得
获奖感言和C语言的学习心得 自我介绍: 大家好,我的名字叫袁忠,我来自湖南,今年快19岁了,现在是大学一年级,我平时喜欢跑步.打羽毛球,我也喜欢学算法与数学,以及喜欢看一些与计算机有关的书籍,每次我学 ...
随机推荐
- NetCore2.0 CodeFirst 解析全国区划信息
NetCore2.0 数据库:SQLite HTML解析:HtmlAgilityPack 区划数据:http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201703/t2 ...
- PAT 乙级 1065 单身狗 (25 分)
1065 单身狗 (25 分) “单身狗”是中文对于单身人士的一种爱称.本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱. 输入格式: 输入第一行给出一个正整数 N(≤ 50 000),是 ...
- 纯CSS制作图形效果
下面所有的例子都是在demo.html的基础上添加相关样式实现的. <!DOCTYPE html> <html> <head> <meta charset=& ...
- mysql数据库优化(四)-项目实战
在flask项目中,防止随着时间的流逝,数据库数据越来越多,导致接口访问数据库速度变慢.所以自己填充数据进行测试及 mysql优化 1.插入数据: 通过脚本,使用多进程,每100次提交数据 impor ...
- gopath环境变量设置
#在国内镜像下载二进制包 wget -c http://www.golangtc.com/static/go/go1.4.1.linux-amd64.tar.gz tar -C /usr/local ...
- EasyARM-iMX283A的U盘使用教程
在编写代码前我们先来EasyARM-iMX283A对U盘使用的操作. 我们先拿一个U盘进行格式化 在U盘中写一些文件保存后,弹出U盘. 将U盘插入EasyARM-iMX283A的开发板. [注意]Ea ...
- This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.
This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.
- 【392】Python 列表解析
参考: Python3 数据结构 | 菜鸟教程 列表推导式 列表推导式提供了从序列创建列表的简单途径.通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据确定的 ...
- linux上安装字体
安装字体命令: yum install wqy-microhei-fonts wqy-zenhei-fonts 安装完字体的存放目录:/usr/share/fonts 默认会在fonts目录下 ...
- Chrome浏览器 调试工具 vue-devtools 的安装和使用
https://www.cnblogs.com/yuqing6/p/7440549.html