最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言學(xué)習(xí)網(wǎng)絡(luò)編程與Http教程示例

 更新時(shí)間:2023年03月28日 09:39:45   作者:香香編程喵喵喵  
這篇文章主要為大家介紹了Go語言學(xué)習(xí)網(wǎng)絡(luò)編程與Http教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

Go語言做網(wǎng)絡(luò)開發(fā)是非常容易的一件事,它已經(jīng)為我們封裝好了Http包,開箱即用。除此之外,我們也可以用Gin框架或者使用fasthttp等三方包,快速搭建一個(gè)Web服務(wù)。但是,越是封裝的方便,我們越是容易忽略底層的一些知識(shí)點(diǎn)。 我們這里先補(bǔ)充兩個(gè)必要的知識(shí):網(wǎng)絡(luò)分層和進(jìn)程通信。

網(wǎng)絡(luò)分層

這塊知識(shí)屬于計(jì)算機(jī)網(wǎng)絡(luò),可以直接去看書。

我們這里直接上圖:

我們最常講的是五層協(xié)議,最重要的是運(yùn)輸層和應(yīng)用層,這兩層是大多數(shù)情況下,工程師可以在代碼中可以直接干預(yù)的模塊,我們大多數(shù)的網(wǎng)絡(luò)編程調(diào)優(yōu),就是在調(diào)這些協(xié)議的一些參數(shù)和細(xì)節(jié)。這兩層的情況:

  • 運(yùn)輸層協(xié)議:TCP和UDP。
  • 應(yīng)用層協(xié)議:Http,SMTP,F(xiàn)TP,WebSocket等等,這些協(xié)議需要使用運(yùn)輸層協(xié)議作為依托。

引申,需要注意TCP和UDP的區(qū)別,和他們具體的使用場景。

順便提一句,網(wǎng)絡(luò)分層本質(zhì)上也是我們反復(fù)提過得加一層的思想,也是高內(nèi)聚低耦合的一種具體的實(shí)現(xiàn)。

進(jìn)程間通信(IPC)

這塊知識(shí)屬于操作系統(tǒng),注意不是Linux操作系統(tǒng),還牽扯一點(diǎn)計(jì)算機(jī)組成原理的知識(shí)。

IPC 是 Inter-Process Communication 的縮寫,可以被翻譯為進(jìn)程間通信。主要方法有: 系統(tǒng)信號(hào)(signal)、管道(pipe)、套接字 (socket)、文件鎖(file lock)、消息隊(duì)列(message queue)、信號(hào)量(semaphore)等。最常用的是系統(tǒng)信號(hào),套接字,還有一個(gè)叫共享內(nèi)存的,能實(shí)現(xiàn),但不提倡。Go底層的os包里也包含著這些常用的方法。

這里需要再引申下,操作系統(tǒng)中進(jìn)程和線程是什么,協(xié)程又是什么。進(jìn)程間是如何通信的,線程間又是如何通信的。

我們單獨(dú)把socket拎出來說,因?yàn)樵诒姸喾桨钢校蛯偎容^通用,比較靈活:使用socket可以跨機(jī)器進(jìn)行通訊。

Socket

實(shí)際上,現(xiàn)代操作系統(tǒng)的內(nèi)核都會(huì)帶有socket相關(guān)的API,我們的代碼在運(yùn)行時(shí),只需要調(diào)用操作系統(tǒng)提供的接口,就可以輕松建立網(wǎng)絡(luò)連接,這也是我們之前講過的面向接口編程的具體場景之一。

Socket網(wǎng)絡(luò)編程的內(nèi)容非常多,我們這里肯定是沒法展開的,推薦大家直接看下: 

https://zhannei.baidu.com/cse/site?q=go&cc=jb51.net&ie=utf

我們這里直接講Go語言中的Socket。在GO語言中有一個(gè)叫做syscall的包,里面有對(duì)應(yīng)的一整套的socket的方法,并且這些方法是做過跨平臺(tái)處理的,我們最常用的Http包里的許多建立連接,接收內(nèi)容的方法都直接或者間接的用了syscall包。

總而言之,我們常用的Http包在建立鏈接時(shí)需要使用到socket,socket建立連接時(shí)需要具體的傳輸層協(xié)議。

Http

基礎(chǔ)知識(shí)

HTTP屬于應(yīng)用層協(xié)議,也就是最頂層協(xié)議。目前他有三個(gè)版本:

  • HTTP1.1 最常用的版本,使用TCP作為運(yùn)輸層協(xié)議。
  • HTTP2 一個(gè)升級(jí)版本,用的不多。同樣使用TCP作為運(yùn)輸層協(xié)議。
  • HTTP3 設(shè)計(jì)了一個(gè)新的傳輸層協(xié)議QUIC,可以選擇TCP或者UDP來傳輸數(shù)據(jù)。

注意,HTTP協(xié)議誕生的年代相當(dāng)久遠(yuǎn),它是一個(gè)無狀態(tài)的協(xié)議。

一個(gè)HTTP的請求有兩部分組成:頭部header和主體body。

//這是一個(gè)GET請求的頭部。
:authority: api.bilibili.com
:method: GET
:path: /x/web-interface/bgroup/member/in?business=MGR&name=PCQoE%E4%BA%BA%E7%BE%A41&dimension=1
:scheme: https
accept: application/json, text/plain, */*
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9,sm;q=0.8,en;q=0.7
cache-control: no-cache
cookie: 
origin: https://www.bilibili.com
pragma: no-cache
referer: https://www.bilibili.com/?utm_source=gold_browser_extension
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36

頭部中有幾個(gè)特別的字段需要關(guān)注下。origin,referer, user-agent, accept。另外,還有幾個(gè)特別的字段:Content-Length,Connection。TCP協(xié)議本身是基于字節(jié)流的,它無法區(qū)分消息邊界,需要應(yīng)用層協(xié)議自己來實(shí)現(xiàn)。

可以詳細(xì)看下Response返回的頭部中都有哪些字段。另外,一些常見的字段我們經(jīng)常在Postman中使用。

客戶端

在Go語言中啟動(dòng)一個(gè)客戶端是相當(dāng)簡單的一件事,Go為HTTP提供了大量的開箱即用的工具。

url := "https://www.bilibili.com" //我們要請求的地址
resp, err := http.Get(url) //get請求,經(jīng)典返回:內(nèi)容和一個(gè)ERR
defer func() {
	_ = resp.Body.Close()  //通常我們需要及時(shí)關(guān)閉掉返回內(nèi)容。
}()
if err != nil {
	fmt.Printf("請求錯(cuò)誤: %v\n", err)
}
fmt.Printf("返回狀態(tài):\n%s\n", resp.Status)

但是,我們通常不會(huì)這樣直接調(diào)用。http.Get的底層調(diào)用的是http.Client,返回的是http.Response。通常情況下,我們會(huì)使用http.Client結(jié)合業(yè)務(wù)場景來構(gòu)造一些請求:

url := "https://www.bilibili.com"
req, _ := http.NewRequest(http.MethodGet, url, nil) //req 是一個(gè)Request結(jié)構(gòu),它有大量的方法的熟悉 可以自定義。
req.Form.Add("test", "1231")                        //構(gòu)造一個(gè)表單提交
req.Header.Set("Cookie", "123")                     //設(shè)置Cookie
resp, err := http.DefaultClient.Do(req) //這里使用的依然是默認(rèn)的DefaultClient
if err != nil {
	fmt.Printf("請求錯(cuò)誤: %v\n", err)
}
defer func() {
	_ = resp.Body.Close()
}()
fmt.Printf("返回狀態(tài):\n%s\n", resp.Status)

正常情況下,我們使用http.DefaultClient.Do,直接調(diào)用默認(rèn)的http.Client就可以正常發(fā)起請求。在某些情況下,公司內(nèi)部會(huì)封裝一個(gè)統(tǒng)一的http.Client,里面會(huì)集成一些公司內(nèi)統(tǒng)一的調(diào)用標(biāo)識(shí),服務(wù)請求方,提供方,trace,機(jī)器編碼,統(tǒng)一的過期時(shí)間等配置信息。

http.Client的結(jié)構(gòu)非常簡單:

type Client struct {
	Transport RoundTripper //真正干活的結(jié)構(gòu)體
	CheckRedirect func(req *Request, via []*Request) error //一個(gè)重定向校驗(yàn)方法,用的比較少
	Jar CookieJar //Cookie包,我們常用的方法都在這個(gè)接口中
	Timeout time.Duration //單次完整HTTP請求的超時(shí)時(shí)間,0代表沒有設(shè)置。
}

如果有時(shí)間,可以看下 DefaultTransport的源碼,通過簡單配置,進(jìn)而理解Http與TCP的一些關(guān)鍵配置項(xiàng)的含義。

最后,如果你愿意也可以自己造個(gè)輪子,但是我們決不提倡這種行為。

conn, err := net.Dial("tcp", "bilibili.com:80")
if err != nil {
	fmt.Printf("connect err => %s\n", err.Error())
}
buf := bytes.Buffer{}
buf.WriteString("GET / HTTP/1.1\r\n")
buf.WriteString("Host: baidu.com\r\n")
buf.WriteString("USer-Agent: Go-http-client/1.1\r\n")
// 請求頭結(jié)束
buf.WriteString("\r\n")
// 請求body結(jié)束
buf.WriteString("\r\n\r\n")
_, _ = conn.Write(buf.Bytes())
// 獲取響應(yīng)信息
resp, _ := io.ReadAll(conn)
fmt.Printf("響應(yīng)信息\n%q", resp)

http.Client的底層是基于net.Dial實(shí)現(xiàn)的,net.Dial底層又調(diào)用了操作系統(tǒng)的Socket相關(guān)接口。

可以嘗試實(shí)現(xiàn)一個(gè)Post方法。

服務(wù)端

Go語言搭建一個(gè)服務(wù)器非常簡單,只需要用到幾個(gè)方法:

http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
	_, _ = fmt.Fprintf(writer, "關(guān)注 香香編程喵喵喵,關(guān)注香香編程謝謝喵喵喵!")
})
panic(http.ListenAndServe(":8080", nil))

http.HandleFunc用來注冊一個(gè)處理器。其內(nèi)部會(huì)持有一個(gè)哈希,用來存儲(chǔ)路徑與處理器的映射關(guān)系。注意,這里和Gin框架就有區(qū)別了。

http.ListenAndServe用來監(jiān)聽一個(gè)端口上的TCP鏈接,并處理后續(xù)的請求。它的底層調(diào)用的是net.Listen,同樣也是基于Socket的方法,我們這里不做展開。

引申

可以這么說,整個(gè)Go的HTTP服務(wù),具體使用上可以直接采用官方包里的方法,其底層細(xì)節(jié)基本上都是Socket的知識(shí)。后續(xù)的學(xué)習(xí)路線可以這樣安排:

  • 學(xué)習(xí)一下HTTP協(xié)議的具體內(nèi)容,關(guān)鍵的配置信息,再看Go的net/http官方包。
  • 學(xué)習(xí)一些網(wǎng)絡(luò)編程的知識(shí),主要是協(xié)議和Socket編程的基礎(chǔ)知識(shí),再看GO的net下的其他包。
  • 注意區(qū)別這些內(nèi)容中容易混淆的概念。

參考 https://zhannei.baidu.com/cse/site?q=go&cc=jb51.net&ie=utf

以上就是Go語言學(xué)習(xí)網(wǎng)絡(luò)編程與Http教程示例的詳細(xì)內(nèi)容,更多關(guān)于Go語言網(wǎng)絡(luò)編程Http教程的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang實(shí)現(xiàn)簡易的rpc調(diào)用

    Golang實(shí)現(xiàn)簡易的rpc調(diào)用

    RPC指(Remote Procedure Call Protocol)遠(yuǎn)程過程調(diào)用協(xié)議。本文將實(shí)現(xiàn)利用Golang進(jìn)行rpc調(diào)用(只實(shí)現(xiàn)一個(gè)rpc框架基本的功能,不對(duì)性能做保證),需要的可以參考一下
    2023-03-03
  • golang之資源釋放/異常錯(cuò)誤處理解析

    golang之資源釋放/異常錯(cuò)誤處理解析

    這篇文章主要為大家介紹了golang之資源釋放/異常錯(cuò)誤處理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Go源碼分析之預(yù)分配slice內(nèi)存

    Go源碼分析之預(yù)分配slice內(nèi)存

    這篇文章主要從Go語言源碼帶大家分析一下預(yù)分配slice內(nèi)存的相關(guān)知識(shí),文中的示例代碼簡潔易懂,對(duì)我們深入了解go有一定的幫助,需要的可以學(xué)習(xí)一下
    2023-08-08
  • Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀

    Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀

    這篇文章主要為大家介紹了Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Go?語言開發(fā)環(huán)境搭建過程

    Go?語言開發(fā)環(huán)境搭建過程

    這篇文章主要介紹了Go?語言開發(fā)環(huán)境搭建過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-03-03
  • golang去除多余的空格與換行符示例代碼

    golang去除多余的空格與換行符示例代碼

    Golang是一種強(qiáng)大的編程語言,提供了豐富的字符串處理功能,這篇文章主要給大家介紹了關(guān)于golang去除多余的空格與換行符的相關(guān)資料,需要的朋友可以參考下
    2023-10-10
  • 為什么Go里值為nil可以調(diào)用函數(shù)原理分析

    為什么Go里值為nil可以調(diào)用函數(shù)原理分析

    這篇文章主要為大家介紹了為什么Go里值為nil可以調(diào)用函數(shù)原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Go實(shí)現(xiàn)整合Logrus實(shí)現(xiàn)日志打印

    Go實(shí)現(xiàn)整合Logrus實(shí)現(xiàn)日志打印

    這篇文章主要介紹了Go實(shí)現(xiàn)整合Logrus實(shí)現(xiàn)日志打印,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-07-07
  • Golang內(nèi)存泄漏場景以及解決方案詳析

    Golang內(nèi)存泄漏場景以及解決方案詳析

    golang中內(nèi)存泄露的發(fā)現(xiàn)與排查一直是來是go開發(fā)者頭疼的一件事,下面這篇文章主要給大家介紹了關(guān)于Golang內(nèi)存泄漏場景以及解決的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • 淺析Go語言中的方法集合與選擇receiver類型

    淺析Go語言中的方法集合與選擇receiver類型

    這篇文章主要為大家詳細(xì)介紹了Go語言中的方法集合與選擇receiver類型的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),對(duì)我們深入學(xué)習(xí)go語言有一定的幫助,需要的可以參考下
    2023-11-11

最新評(píng)論

潞城市| 普陀区| 龙口市| 海丰县| 平山县| 石棉县| 昌图县| 樟树市| 军事| 扶风县| 江门市| 仁布县| 六安市| 登封市| 灵台县| 共和县| 青海省| 许昌县| 南阳市| 平阴县| 江山市| 伊春市| 冀州市| 浮山县| 邢台市| 马关县| 岳普湖县| 黄平县| 台湾省| 河西区| 民乐县| 九龙城区| 三穗县| 高要市| 定襄县| 高阳县| 合江县| 北流市| 西丰县| 梧州市| 新沂市|