欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言七篇入門教程六網(wǎng)絡(luò)編程

 更新時(shí)間:2021年11月09日 16:55:24   作者:小生凡一  
這篇文章主要為大家介紹了Go語言的網(wǎng)絡(luò)編程,其中包含了Socket編程,Http編程以及RPC編程,本篇文章是Go語言七篇入門系列文章,有需要的朋友可以借鑒下

1. Socket 編程

在 Go 語言中編寫網(wǎng)絡(luò)程序時(shí),我們將看不到傳統(tǒng)的編碼形式。以前我們使用 Socket 編程時(shí),會(huì)按照如下步驟展開。

建立 Socket:使用 socket()函數(shù)。

綁定 Socket:使用 bind()函數(shù)。

監(jiān)聽:使用 listen()函數(shù)?;蛘哌B接:使用 connect()函數(shù)。

接受連接:使用 accept()函數(shù)。

接收:使用 receive()函數(shù)?;蛘甙l(fā)送:使用 send()函數(shù)。
Go 語言標(biāo)準(zhǔn)庫(kù)對(duì)此過程進(jìn)行了抽象和封裝。無論我們期望使用什么協(xié)議建立什么形式的連接,都只需要調(diào)用 net.Dial()即可。

1.1 Dial()函數(shù)

Dial()函數(shù)的原型如下:

func Dial(net, addr string) (Conn, error)

其中 net 參數(shù)是網(wǎng)絡(luò)協(xié)議的名字,addr 參數(shù)是IP 地址或域名,而端口號(hào)以:的形式跟隨在地址或域名的后面,端口號(hào)可選。如果連接成功,返回連接對(duì)象,否則返回 error
我們來看一下幾種常見協(xié)議的調(diào)用方式。

TCP 鏈接:

conn, err := net.Dial("tcp", "192.168.1.8:3000")

UDP鏈接:

conn, err := net.Dial("udp", "192.168.1.12:975")

ICMP鏈接(使用協(xié)議名稱):

conn, err := net.Dial("ip4:icmp", "www.baidu.com")

ICMP鏈接(使用協(xié)議編號(hào)):

conn, err := net.Dial("ip4:1", "10.0.0.3")

在成功建立連接后,我們就可以進(jìn)行數(shù)據(jù)的發(fā)送和接收。發(fā)送數(shù)據(jù)時(shí),使用 connWrite()成員方法,接收數(shù)據(jù)時(shí)使用 Read()方法。

2. HTTP 編程

2.1 HTTP 客戶端

Go 內(nèi)置的 net/http 包提供了最簡(jiǎn)潔的 HTTP 客戶端實(shí)現(xiàn),我們無需借助第三方網(wǎng)絡(luò)通信庫(kù)(比如 libcurl)就可以直接使用 HTTP 中用得最多的 GETPOST 方式請(qǐng)求數(shù)據(jù)。

基本方法

net/http 包的 Client 類型提供了如下幾個(gè)方法,讓我們可以用最簡(jiǎn)潔的方式實(shí)現(xiàn)HTTP 請(qǐng)求:

func (c *Client) Get(url string) (r *Response, err error)
func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response, err error)
func (c *Client) PostForm(url string, data url.Values) (r *Response, err error)
func (c *Client) Head(url string) (r *Response, err error)
func (c *Client) Do(req *Request) (resp *Response, err error)

下面概要介紹這幾個(gè)方法。

  • http.Get()

要請(qǐng)求一個(gè)資源,只需調(diào)用 http.Get()方法(等價(jià)于 http.DefaultClient.Get())即可,示例代碼如下:

resp, err := http.Get("http://example.com/")
if err != nil { // 處理錯(cuò)誤 ...
	return
}
defer resp.Body.close()
io.Copy(os.Stdout, resp.Body)

上面這段代碼請(qǐng)求一個(gè)網(wǎng)站首頁,并將其網(wǎng)頁內(nèi)容打印到標(biāo)準(zhǔn)輸出流中。

  • http.Post()

要以POST 的方式發(fā)送數(shù)據(jù),也很簡(jiǎn)單,只需調(diào)用 http.Post()方法并依次傳遞下面的 3 個(gè)參數(shù)即可:

請(qǐng)求的目標(biāo) URL將要 POST 數(shù)據(jù)的資源類型(MIMEType)數(shù)據(jù)的比特流([]byte 形式)

下面的示例代碼演示了如何上傳一張圖片:

resp, err := http.Post("http://example.com/upload", "image/jpeg", &imageDataBuf)
if err != nil{ // 處理錯(cuò)誤
	return
}
if resp.StatusCode != http.StatusOK {// 處理錯(cuò)誤
	return
}
  • http.PostForm()

http.PostForm()方法實(shí)現(xiàn)了標(biāo)準(zhǔn)編碼格式為 application/x-www-form-urlencoded的表單提交。下面的示例代碼模擬 HTML 表單提交一篇新文章:

resp, err := http.PostForm("http://example.com/posts", url.Values{"title": 
{"article title"}, "content": {"article body"}})
if err != nil{ // 處理錯(cuò)誤
	return
}
  • http.Head()

HTTP 中的 Head 請(qǐng)求方式表明只請(qǐng)求目標(biāo) URL 的頭部信息,即 HTTP Header 而不返回 HTTP
Body。Go 內(nèi)置的 net/http 包同樣也提供了 http.Head() 方法,該方法同 http.Get() 方法一樣,
只需傳入目標(biāo) URL 一個(gè)參數(shù)即可。下面的示例代碼請(qǐng)求一個(gè)網(wǎng)站首頁的 HTTP Header 信息:

resp, err := http.Head("http://baidu.com/")
  • (*http.Client).Do()

在多數(shù)情況下,http.Get()http.PostForm() 就可以滿足需求,但是如果我們發(fā)起的
HTTP 請(qǐng)求需要更多的定制信息,我們希望設(shè)定一些自定義的 Http Header 字段,比如:

  • 設(shè)定自定義的"User-Agent"
  • 傳遞 Cookie

此時(shí)可以使用 net/httphttp.Client對(duì)象的 Do()方法來實(shí)現(xiàn)

req, err := http.NewRequest("GET", "http://baidu.com", nil) 
// ...
req.Header.Add("User-Agent", "Gobook Custom User-Agent") 
// ...
client := &http.Client{ //... } 
resp, err := client.Do(req)

2.2 HTTP 服務(wù)端

2.2.1 處理 HTTP 請(qǐng)求

使用 net/http 包提供的 http.ListenAndServe() 方法,可以在指定的地址進(jìn)行監(jiān)聽,開啟一個(gè) HTTP,服務(wù)端該方法的原型如下:

func ListenAndServe(addr string, handler Handler) error

該方法用于在指定的 TCP 網(wǎng)絡(luò)地址 addr 進(jìn)行監(jiān)聽,然后調(diào)用服務(wù)端處理程序來處理傳入的連接請(qǐng)求。該方法有兩個(gè)參數(shù):第一個(gè)參數(shù) addr 即監(jiān)聽地址;第二個(gè)參數(shù)表示服務(wù)端處理程序,通常為空,這意味著服務(wù)端調(diào)用 http.DefaultServeMux 進(jìn)行處理,而服務(wù)端編寫的業(yè)務(wù)邏輯處理程序 http.Handle()http.HandleFunc() 默認(rèn)注入 http.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))

net/http 包還提供 http.ListenAndServeTLS() 方法,用于處理 HTTPS 連接請(qǐng)求:

func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error

ListenAndServeTLS()ListenAndServe() 的行為一致,區(qū)別在于只處理 HTTPS 請(qǐng)求。此外,服務(wù)器上必須存在包含證書和與之匹配的私鑰的相關(guān)文件,比如 certFile 對(duì)應(yīng) SSL證書文件存放路徑,keyFile 對(duì)應(yīng)證書私鑰文件路徑。如果證書是由證書頒發(fā)機(jī)構(gòu)簽署的,certFile 參數(shù)指定的路徑必須是存放在服務(wù)器上的經(jīng)由 CA認(rèn)證過的 SSL 證書。

3. RPC 編程

在 Go 中,標(biāo)準(zhǔn)庫(kù)提供的 net/rpc 包實(shí)現(xiàn)了 RPC 協(xié)議需要的相關(guān)細(xì)節(jié),開發(fā)者可以很方便地使用該包編寫 RPC 的服務(wù)端和客戶端程序,這使得用 Go 語言開發(fā)的多個(gè)進(jìn)程之間的通信變得非常簡(jiǎn)單。

net/rpc 包允許 RPC 客戶端程序通過網(wǎng)絡(luò)或是其他 I/O 連接調(diào)用一個(gè)遠(yuǎn)端對(duì)象的公開方法(必須是大寫字母開頭、可外部調(diào)用的)。在 RPC 服務(wù)端,可將一個(gè)對(duì)象注冊(cè)為可訪問的服務(wù),之后該對(duì)象的公開方法就能夠以遠(yuǎn)程的方式提供訪問。一個(gè) RPC 服務(wù)端可以注冊(cè)多個(gè)不同類型的對(duì)象,但不允許注冊(cè)同一類型的多個(gè)對(duì)象。

一個(gè)對(duì)象中只有滿足如下這些條件的方法,才能被 RPC 服務(wù)端設(shè)置為可供遠(yuǎn)程訪問:

  • 必須是在對(duì)象外部可公開調(diào)用的方法(首字母大寫);
  • 必須有兩個(gè)參數(shù),且參數(shù)的類型都必須是包外部可以訪問的類型或者是 Go 內(nèi)建支持的類型;
  • 第二個(gè)參數(shù)必須是一個(gè)指針;
  • 方法必須返回一個(gè) error 類型的值。

以上 4 個(gè)條件,可以簡(jiǎn)單地用如下一行代碼表示:

func (t *T) MethodName(argType T1, replyType *T2) error

在上面這行代碼中,類型 T、T1 和 T2 默認(rèn)會(huì)使用 Go 內(nèi)置的 encoding/gob 包進(jìn)行編碼解碼。

該方法(MethodName)的第一個(gè)參數(shù)表示由 RPC 客戶端傳入的參數(shù),第二個(gè)參數(shù)表示要返回給 RPC 客戶端的結(jié)果,該方法最后返回一個(gè) error 類型的值。
RPC 服務(wù)端可以通過調(diào)用 rpc.ServeConn 處理單個(gè)連接請(qǐng)求。多數(shù)情況下,通過 TCP 或是 HTTP 在某個(gè)網(wǎng)絡(luò)地址上進(jìn)行監(jiān)聽來創(chuàng)建該服務(wù)是個(gè)不錯(cuò)的選擇。

3.1 Go 語言中的 RPC 支持與處理

在 Go 中,標(biāo)準(zhǔn)庫(kù)提供的net/rpc包實(shí)現(xiàn)了RPC 協(xié)議需要的相關(guān)細(xì)節(jié),開發(fā)者可以很方便地使用該包編寫 RPC 的服務(wù)端和客戶端程序,這使得用 Go 語言開發(fā)的多個(gè)進(jìn)程之間的通信變得非常簡(jiǎn)單。

net/rpc 包允許 RPC 客戶端程序通過網(wǎng)絡(luò)或是其他 I/O 連接調(diào)用一個(gè)遠(yuǎn)端對(duì)象的公開方法(必須是大寫字母開頭、可外部調(diào)用的)。在RPC服務(wù)端,可將一個(gè)對(duì)象注冊(cè)為可訪問的服務(wù),之后該對(duì)象的公開方法就能夠以遠(yuǎn)程的方式提供訪問。一個(gè)RPC服務(wù)端可以注冊(cè)多個(gè)不同類型的對(duì)象,但不允許注冊(cè)同一類型的多個(gè)對(duì)象。

一個(gè)對(duì)象中只有滿足如下這些條件的方法,才能被RPC服務(wù)端設(shè)置為可供遠(yuǎn)程訪問:

  • 必須是在對(duì)象外部可公開調(diào)用的方法(首字母大寫);
  • 必須有兩個(gè)參數(shù),且參數(shù)的類型都必須是包外部可以訪問的類型或者是Go內(nèi)建支持的類型;
  • 第二個(gè)參數(shù)必須是一個(gè)指針;
  • 方法必須返回一個(gè) error 類型的值。

以上 4 個(gè)條件,可以簡(jiǎn)單地用如下一行代碼表示:

func (t *T) MethodName(argType T1, replyType *T2) error

在上面這行代碼中,類型 T、T1 和 T2 默認(rèn)會(huì)使用 Go 內(nèi)置的 encoding/gob 包進(jìn)行編碼解碼。關(guān)于 encoding/gob 包的內(nèi)容,稍后我們將會(huì)對(duì)其進(jìn)行介紹。

該方法(MethodName)的第一個(gè)參數(shù)表示由 RPC 客戶端傳入的參數(shù),第二個(gè)參數(shù)表示要返回給 RPC 客戶端的結(jié)果,該方法最后返回一個(gè) error 類型的值。

RPC 服務(wù)端可以通過調(diào)用 rpc.ServeConn 處理單個(gè)連接請(qǐng)求。多數(shù)情況下,通過 TCP 或是 HTTP 在某個(gè)網(wǎng)絡(luò)地址上進(jìn)行監(jiān)聽來創(chuàng)建該服務(wù)是個(gè)不錯(cuò)的選擇。

3.2 Gob 簡(jiǎn)介

Gob 是 Go 的一個(gè)序列化數(shù)據(jù)結(jié)構(gòu)的編碼解碼工具,在Go標(biāo)準(zhǔn)庫(kù)中內(nèi)置 encoding/gob包以供使用。一個(gè)數(shù)據(jù)結(jié)構(gòu)使用 Gob進(jìn)行序列化之后,能夠用于網(wǎng)絡(luò)傳輸。

JSONXML這種基于文本描述的數(shù)據(jù)交換語言不同,Gob是二進(jìn)制編碼的數(shù)據(jù)流,并且 Gob 流是可以自解釋的,它在保證高效率的同時(shí),也具備完整的表達(dá)能力。

作為針對(duì) Go的數(shù)據(jù)結(jié)構(gòu)進(jìn)行編碼和解碼的專用序列化方法,這意味著 Gob 無法跨語言使用。在 Gonet/rpc 包中,傳輸數(shù)據(jù)所需要用到的編碼解碼器,默認(rèn)就是 Gob。由于Gob 僅局限于使用 Go 語言開發(fā)的程序,這意味著我們只能用 GoRPC 實(shí)現(xiàn)進(jìn)程間通信。

然而,大多數(shù)時(shí)候,我們用Go編寫的 RPC 服務(wù)端(或客戶端),可能更希望它是通用的,與語言無關(guān)的,無論是 Python 、 Java 或其他編程語言實(shí)現(xiàn)的 RPC 客戶端,均可與之通信。

3.3 設(shè)計(jì)優(yōu)雅的 RPC 接口

Go 的 net/rpc 很靈活,它在數(shù)據(jù)傳輸前后實(shí)現(xiàn)了編碼解碼器的接口定義。這意味著,開發(fā)者可以自定義數(shù)據(jù)的傳輸方式以及 RPC 服務(wù)端和客戶端之間的交互行為。
RPC 提供的編碼解碼器接口如下:

type ClientCodec interface {
	WriteRequest(*Request, interface{}) error 
	ReadResponseHeader(*Response) error
	ReadResponseBody(interface{}) error
	Close() error
}

type ServerCodec interface {
	ReadRequestHeader(*Request) error 
	ReadRequestBody(interface{}) error 
	WriteResponse(*Response, interface{}) error
	Close() error
}

接口 ClientCodec 定義了 RPC 客戶端如何在一個(gè) RPC 會(huì)話中發(fā)送請(qǐng)求和讀取響應(yīng)。客戶端程序通過 WriteRequest() 方法將一個(gè)請(qǐng)求寫入到 RPC 連接中,并通過ReadResponseHeader()ReadResponseBody() 讀取服務(wù)端的響應(yīng)信息。當(dāng)整個(gè)過程執(zhí)行完畢后,再通過 Close()方法來關(guān)閉該連接。

接口 ServerCodec 定義了 RPC 服務(wù)端如何在一個(gè) RPC 會(huì)話中接收請(qǐng)求并發(fā)送響應(yīng)。服務(wù)端程序通過ReadRequestHeader()ReadRequestBody() 方法從一個(gè) RPC 連接中讀取 請(qǐng)求信息,然后再通過WriteResponse() 方法向該連接中的 RPC 客戶端發(fā)送響應(yīng)。當(dāng)完成該過程后,通過 Close()方法來關(guān)閉連接。

通過實(shí)現(xiàn)上述接口,我們可以自定義數(shù)據(jù)傳輸前后的編碼解碼方式,而不僅僅局限于Gob。同樣,可以自定義RPC服務(wù)端和客戶端的交互行為。實(shí)際上,Go 標(biāo)準(zhǔn)庫(kù)提供的 net/rpc/json包,就是一套實(shí)現(xiàn)了 rpc.ClientCodecrpc.ServerCodec 接口的 JSON-RPC 模塊。

以上就是Go語言七篇入門教程六網(wǎng)絡(luò)編程第的詳細(xì)內(nèi)容,更多關(guān)于Go語言網(wǎng)絡(luò)編程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

如何學(xué)習(xí)Go

如果你是小白,你可以這樣學(xué)習(xí)Go語言~

七篇入門Go語言

第一篇:Go簡(jiǎn)介初識(shí)

第二篇:程序結(jié)構(gòu)&&數(shù)據(jù)類型的介紹

第三篇:函數(shù)方法接口的介紹

第四篇:通道與Goroutine的并發(fā)編程

第五篇:文件及包的操作與處理

第七篇:GC垃圾回收三色標(biāo)記

相關(guān)文章

  • 在Go中格式化字符串的幾種常用方法

    在Go中格式化字符串的幾種常用方法

    Go對(duì)字符串格式化提供了良好的支持,這篇文章主要給大家介紹了關(guān)于在Go中格式化字符串的幾種常用方法,文中通過代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Go具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-10-10
  • 淺談go build后加文件和目錄的區(qū)別

    淺談go build后加文件和目錄的區(qū)別

    這篇文章主要介紹了淺談go build后加文件和目錄的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang中切片的用法與本質(zhì)詳解

    Golang中切片的用法與本質(zhì)詳解

    Go的切片類型為處理同類型數(shù)據(jù)序列提供一個(gè)方便而高效的方式,下面這篇文章就來給大家介紹了關(guān)于Golang中切片的用法與本質(zhì)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-07-07
  • go?doudou應(yīng)用中使用注解示例詳解

    go?doudou應(yīng)用中使用注解示例詳解

    這篇文章主要為大家介紹了go?doudou應(yīng)用中使用注解示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Go語言實(shí)現(xiàn)新春祝福二維碼的生成

    Go語言實(shí)現(xiàn)新春祝福二維碼的生成

    二維碼現(xiàn)在是隨處度可以看到,買東西,支付,添加好友只要你掃一掃就能完成整個(gè)工作,簡(jiǎn)單且方便。所以利用這個(gè)新春佳節(jié)做一個(gè)帶著新春祝福的二維碼吧
    2023-02-02
  • Go GORM版本2.0新特性介紹

    Go GORM版本2.0新特性介紹

    這篇文章主要為大家介紹了Go GORM版本2.0新特性的使用示例介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • goland中導(dǎo)包報(bào)紅和go mod問題

    goland中導(dǎo)包報(bào)紅和go mod問題

    這篇文章主要介紹了goland中導(dǎo)包報(bào)紅和go mod問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 一文深入探索Go語言中的循環(huán)結(jié)構(gòu)

    一文深入探索Go語言中的循環(huán)結(jié)構(gòu)

    在編程中,循環(huán)結(jié)構(gòu)扮演著重要的角色,它使我們能夠有效地重復(fù)執(zhí)行特定的代碼塊,以實(shí)現(xiàn)各種任務(wù)和邏輯,在Go語言中,for 是 Go 中唯一的循環(huán)結(jié)構(gòu),本文將深入探討Go語言中的for循環(huán)類型以及它們的用法
    2023-08-08
  • Go實(shí)現(xiàn)分布式唯一ID的生成之雪花算法

    Go實(shí)現(xiàn)分布式唯一ID的生成之雪花算法

    本文主要介紹了Go實(shí)現(xiàn)分布式唯一ID的生成之雪花算法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Go http client 連接池不復(fù)用的問題

    Go http client 連接池不復(fù)用的問題

    這篇文章主要介紹了Go http client 連接池不復(fù)用的問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01

最新評(píng)論