Go語言程序設計及實例 課件 第7章 Go網絡編程_第1頁
Go語言程序設計及實例 課件 第7章 Go網絡編程_第2頁
Go語言程序設計及實例 課件 第7章 Go網絡編程_第3頁
Go語言程序設計及實例 課件 第7章 Go網絡編程_第4頁
Go語言程序設計及實例 課件 第7章 Go網絡編程_第5頁
已閱讀5頁,還剩49頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第7章Go網絡編程Socket編程01Socket概述Socket概述Socket是用于在計算機網絡中兩個應用進程間發送和接收數據的端點,其中包含通信協議、目標地址、連接狀態等,作為一種網絡資源,它本質上就是對傳輸層協議(TCP/UDP)的運用進行了一層封裝,讓應用程序能夠更方便地使用傳輸層來傳輸數據。主流操作系統(Windows/Linux/MacOS等)都提供了統一的套接字抽象編程接口(SocketAPI),開發人員平時編寫的網絡程序大多處于應用層,它們直接調用SocketAPI接口進行通信,故Socket在網絡中所處的位置大致位于應用層的底部、傳輸層之上(如圖所示),起到連接這兩層的關鍵作用。02TCP程序設計1.TCP原理2.TCP編程TCP程序設計1.TCP原理一個典型的TCP傳輸文件的過程如下:(1)首先啟動服務器,一段時間后啟動客戶端,它與此服務器經過三次握手后建立連接。(2)此后的一段時間內,客戶端向服務器發送一個請求,服務器處理這個請求,并為客戶端發回一個響應。這個過程一直持續下去,直到客戶端向服務器發一個文件結束符,并關閉客戶端連接。(3)接著服務器也關閉服務器端的連接,結束運行或等待一個新的客戶端連接。以上TCP客戶端與TCP服務器間的交互時序如圖。TCP程序設計2.TCP編程Go語言TCP編程的通行步驟如下。(1)封裝地址用net.ResolveTCPAddr方法封裝TCP地址,形式為:地址,錯誤:=net.ResolveTCPAddr("tcp","主機:端口")返回的“地址”是一個TCPAddr類型的指針。(2)監聽地址服務器通過net.ListenTCP方法監聽第(1)步封裝的TCP地址,等待客戶端的請求,語句形式為:監聽器,錯誤:=net.ListenTCP("tcp",地址)這里創建的監聽器是*TCPListener類型。(3)發起連接客戶端通過net.DialTCP方法向服務器監聽的地址發起連接請求,如下:連接,錯誤:=net.DialTCP("tcp",nil,地址)返回的“連接”是TCPConn類型的指針。TCP程序設計(4)接受連接服務器在循環中用監聽器的AcceptTCP方法隨時接受到來的連接請求:連接,錯誤:=監聽器.AcceptTCP()這里的“連接”是由監聽器創建的用于與客戶端Socket連接的結構體,類型也是TCPConn的指針。(5)傳輸數據接下來的數據傳輸就在雙方連接(TCPConn類型的結構體)對象之間進行,用Read方法接收數據,Write方法發送數據,形如:長度,錯誤:=連接.Read(數據) //接收數據長度,錯誤:=連接.Write(數據) //發送數據收發的數據都是字節切片([]byte)類型。TCP程序設計【實例7.1】用TCP實現客戶端向服務器上傳文本文件。開發步驟如下。(1)實現思路及準備客戶端首先將要上傳的文件名發給服務器,服務器在自己的資源目錄下創建此名稱的文本文件;然后客戶端將文件內容讀取出來發送到服務器端,服務器程序再將傳來的內容寫入文件即可。本例以D:\Go\下載Go學習資源\2023\08\01下面的“Go語言.txt”文件做測試,服務器資源目錄為D:\res\files,需要事先創建好。(2)服務器端開發編寫服務器程序代碼如下(file-server.go):(3)客戶端開發編寫客戶端程序代碼如下(file-client.go):TCP程序設計(4)運行程序先啟動服務器程序再啟動客戶端,在客戶端子窗口提示符處輸入文件名“Go語言”回車,運行結果如圖。此時進入到D:\res\files目錄下可看到上傳的文件“Go語言.txt”。服務器輸出客戶端輸出03UDP程序設計1.UDP原理2.UDP編程UDP程序設計1.UDP原理UDP(UserDatagramProtocol,用戶數據報協議)是一種簡單、輕量、無連接的傳輸協議,可以用在對通信可靠性要求不是很高的場合,如以下幾種情形:網絡數據大多為短消息。系統擁有大量客戶端。對數據安全性無特殊要求。網絡負載很重,但對響應速度卻要求極高。UDP所收發數據的形式是報文(Datagram),通信時UDP客戶端向UDP服務器發送一定長度的請求報文,報文大小的限制與各系統的協議實現有關,但不得超過其下層IP規定的64KB,UDP服務器同樣以報文做出應答,如圖。UDP程序設計在UDP方式下,客戶端并不與服務器建立連接,它只負責調用發送函數向服務器發出數據報。類似地,服務器也不接受客戶端的連接,只是調用接收函數被動等待來自某客戶端的數據到達。UDP客戶端與UDP服務器間的交互時序如圖。UDP程序設計UDP與TCP的比較見表。比較項UDPTCP是否連接無連接面向連接傳輸可靠性不可靠可靠流量控制不提供提供工作方式可以是全雙工全雙工應用場合少量數據大量數據速度快慢UDP程序設計2.UDP編程Go語言UDP編程的通行步驟如下。(1)封裝地址用net.ResolveUDPAddr方法封裝UDP地址,形式為:地址,錯誤:=net.ResolveUDPAddr("udp","主機:端口")返回的“地址”是一個UDPAddr類型的指針。(2)監聽地址服務器通過net.ListenUDP方法監聽第(1)步封裝的UDP地址,語句為:監聽器,錯誤:=net.ListenUDP("udp",地址)(3)建立連接客戶端通過net.DialUDP方法與服務器的監聽器建立連接,如下:連接,錯誤:=net.DialUDP("udp",nil,地址)返回的“連接”也是UDPConn類型的指針,它無須經服務器接受,直接就能與服務器端的監聽器通信。UDP程序設計(4)收發數據UDP數據的收發在服務器端監聽器與客戶端連接(兩者同為UDPConn類型的結構體)之間進行,用ReadFromUDP方法接收數據,WriteToUDP方法發送數據,形如:長度,地址,錯誤:=連接.ReadFromUDP(數據) //接收數據連接.WriteToUDP(數據,地址) //發送數據UDP收發的數據也都是字節切片([]byte)類型。【實例7.2】用UDP模擬即時通訊軟件(如微信、QQ等)的用戶加入群聊時與服務器的交互。開發步驟如下。(1)服務器端開發編寫服務器程序代碼如下(group-server.go):(2)客戶端開發編寫客戶端程序代碼如下(group-client.go):UDP程序設計(3)運行程序先啟動服務器程序再啟動客戶端,在客戶端子窗口提示符處輸入用戶名“周何駿”回車,運行結果如圖。服務器輸出客戶端輸出第7章Go網絡編程HTTP編程01最簡單的HTTP程序最簡單的HTTP程序Go語言有net/http包專用于實現HTTP功能,一個最簡單的HTTP程序由服務器和客戶端兩部分組成,客戶端向服務器上的復用器發出HTTP請求,復用器根據請求的URL找到預先注冊的對應處理器,將請求交給處理器處理,處理器執行程序邏輯得到結果,再將結果寫入HTTP響應體后返回給客戶端,整個過程如圖。最簡單的HTTP程序這個過程的Go語言實現方式如下。(1)服務器服務器端需要編寫實現一個處理器函數,將這個函數注冊到復用器中,然后在指定服務地址上開啟監聽,等待客戶端請求的到來。①實現處理器實現處理器就是編寫相應的處理器函數,處理器函數有固定類型的兩個參數,寫法為:func函數名(參數1http.ResponseWriter,參數2*http.Request){ ...//執行處理邏輯的代碼}②注冊處理器用戶編寫的處理器必須注冊才能使用,net/http包提供一個HandleFunc函數用于在指定的URL路徑上注冊處理器,語句寫法為:http.HandleFunc(URL路徑,函數名)最簡單的HTTP程序③開啟監聽一切準備就緒后,服務器調用ListenAndServe函數開啟監聽,就可以向客戶端提供服務了,語句如下:http.ListenAndServe(地址,nil)如果需要對服務器進行更多配置,可先創建一個http.Server結構體對象,指定對其特定的參數進行初始化,然后再調用ListenAndServe函數,代碼形如://配置服務器server:=&http.Server{

參數1:值1,

參數2:值2, ...

參數n:值n,}server.ListenAndServe() //開啟監聽最簡單的HTTP程序(2)客戶端客戶端需要能創建HTTP請求和解析HTTP響應。①創建HTTP請求Go使用NewRequest函數創建HTTP請求,語句為:請求,錯誤:=http.NewRequest(方法,URL,請求體)②解析HTTP響應net/http包中提供了一個模擬客戶端的Client結構體,通過調用其Do方法來獲取一個HTTP請求對應的響應,語句如下:客戶端:=&http.Client{}響應,錯誤:=客戶端.Do(請求)Go對最常用的GET和POST請求還做了進一步封裝,因此也可以不用模擬客戶端而直接通過Get或Post函數獲取到響應,例如:響應,錯誤:=http.Get(URL)最簡單的HTTP程序【實例7.3】服務器在收到請求后向客戶端返回一句話:

“Hello,我愛Go語言!@easybooks”。開發步驟如下。(1)服務器編寫服務器程序代碼如下(hello-server.go):packagemainimport( "fmt" "net/http" //Go語言HTTP編程包)//實現處理器funcsayhello(whttp.ResponseWriter,req*http.Request){ fmt.Fprintf(w,"Hello,我愛Go語言!@easybooks\n") //w.Write([]byte("Hello,我愛Go語言!@easybooks\n")) //也可以用這句}

funcmain(){ http.HandleFunc("/hello",sayhello) //注冊處理器 http.ListenAndServe(":8080",nil) //開啟監聽 //或者用下面這段代碼 //server:=&http.Server{ // Addr:":8080", //配置地址參數 //} //server.ListenAndServe()}最簡單的HTTP程序(2)客戶端編寫客戶端程序代碼如下(hello-client.go):packagemainimport( "fmt" "io/ioutil" "net/http" //Go語言HTTP編程包)

funcmain(){ //創建HTTP請求 req,_:=http.NewRequest("GET",":8080/hello",nil) //解析HTTP響應 client:=&http.Client{} rsp,_:=client.Do(req)

//rsp,_:=http.Get(":8080/hello") //或者用這句替代上面3句 //輸出顯示響應體中的數據內容 contents,_:=ioutil.ReadAll(rsp.Body) fmt.Println(string(contents))}最簡單的HTTP程序(3)運行程序先啟動服務器程序再啟動客戶端,從客戶端子窗口中可看到輸出,或者通過瀏覽器訪問:8080/hello也能看到同樣的輸出內容,運行結果如圖。客戶端輸出瀏覽器輸出02使用模板引擎使用模板引擎網頁本質上是一個HTML文檔,其中大部分內容(如框架、樣式、主題、頁尾聲明等)都是固定不變的,變化的只是業務數據,于是可將不變的部分提取出來作為“模板”,而可變部分則由處理器在運行時提供數據,借助模板引擎渲染來合成動態網頁,如圖所示。使用模板引擎Go語言內置了文本模板引擎text/template包,開發使用模板引擎的HTTP程序的通行步驟如下。(1)定義模板模板文件通常是.html網頁文件,也可以是.tmpl或.tpl后綴的文件,但都必須使用UTF-8編碼。用戶要按一定的語法規則編寫模板內容,基本規則如下:模板中使用“{{”和“}}”來包裹和標識需要傳入的數據。傳給模板的數據可以通過點號(.)來訪問。如果是復合類型的數據,則可以通過“{{.字段名}}”來訪問它的字段。除“{{”和“}}”包裹的內容外,其他內容均不做修改原樣輸出。使用模板引擎(2)解析模板解析模板使用ParseFiles函數,該函數接收模板文件名作為參數,返回一個模板對象(Template)類型的指針,調用語句如下:模板對象,錯誤:=template.ParseFiles(模板文件)(3)渲染模板最后,通過調用模板對象的Execute方法來渲染模板,語句如下:模板對象.Execute(HTTP響應體,數據)使用模板引擎【實例7.4】使用模板引擎在瀏覽器中輸出一句話:

“Hello,我愛Go語言!@easybooks”。開發步驟如下。(1)定義模板在當前GoLand項目目錄下創建模板文件,編寫內容如下(hello-view.html):<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>我喜愛的編程語言</title><style>.myfont{font-family:"華文楷體";font-size:x-large;font-weight:bold;color:limegreen;}</style></head><body><divclass="myfont">Hello,我愛{{.Language}}語言!@{{.User}}</div></body></html>使用模板引擎(2)解析、渲染模板解析和渲染模板的代碼都寫在服務器的處理器函數中,如下(hello-template.go):packagemainimport( "net/http" "text/template" //Go語言模板引擎包)typeContentsstruct{ //存儲數據的結構體 Languagestring Userstring}//處理器函數funcrenderhello(whttp.ResponseWriter,req*http.Request){ tmpl,_:=template.ParseFiles("./hello-view.html") //解析模板 contents:=Contents{ Language:"Go", User:"easybooks", } //產生數據內容 tmpl.Execute(w,contents) //渲染模板}

funcmain(){ http.HandleFunc("/hello",renderhello) http.ListenAndServe(":8080",nil)}使用模板引擎(3)運行程序啟動服務器,通過瀏覽器訪問:8080/hello,運行結果如圖。瀏覽器輸出客戶端輸出03請求多路復用請求多路復用多路復用的HTTP程序工作過程如圖。請求多路復用【實例7.5】使用多路復用器分別以中英文輸出對Go語言的問候。編寫服務器程序代碼如下(hello-handle.go):packagemainimport( "fmt" "net/http")typeContentsstruct{ //作為處理器類的結構體 Languagestring Userstring}//處理器的ServeHTTP方法func(cContents)ServeHTTP(whttp.ResponseWriter,req*http.Request){ fmt.Fprintf(w,c.Language)}

funcmain(){ mux:=http.NewServeMux() //創建多路復用器 mux.Handle("/hello/cn",Contents{Language:"您好,我愛Go語言!@易斯\n"}) mux.Handle("/hello/en",Contents{Language:"Hello,IloveGolanguage!@easybooks\n"}) //不同的URL分別定向至不同的處理器實例 server:=&http.Server{ Addr:":8080", Handler:mux, //配置復用器 } server.ListenAndServe()}請求多路復用或者,也可以采用處理器函數的方式來實現多路復用功能,如下(hello-handlefunc.go):packagemainimport( "fmt" "net/http")

funccnHandler(whttp.ResponseWriter,req*http.Request){ fmt.Fprintf(w,"您好,我愛Go語言!@易斯\n")} //處理器函數1(輸出中文問候語)funcenHandler(whttp.ResponseWriter,req*http.Request){ fmt.Fprintf(w,"Hello,IloveGolanguage!@easybooks\n")} //處理器函數2(輸出英文問候語)

funcmain(){ mux:=http.NewServeMux() //創建多路復用器 //將兩個處理器函數注冊到復用器中 mux.HandleFunc("/hello/cn",cnHandler) mux.HandleFunc("/hello/en",enHandler) server:=&http.Server{ Addr:":8080", Handler:mux, //配置復用器 } server.ListenAndServe()}請求多路復用以上兩個程序的運行方式和結果都是完全一樣的。啟動服務器,通過瀏覽器訪問:8080/hello/cn,輸出中文問候語;訪問:8080/hello/en則輸出英文問候語,運行結果如圖。輸出中文問候語輸出英文問候語04表單提交處理表單提交處理在HTTP編程中,可從處理器函數的第2個參數(HTTP請求體)中獲取頁面表單提交的數據,只要執行語句:請求體.ParseForm()即可解析出表單數據,數據是鍵值對的形式,可用如下語句得到對應鍵的值:值:=請求體.Form.Get(鍵名)【實例7.6】在表單中輸入編程語言及用戶名,提交后用模板顯示對該語言的問候。開發步驟如下。(1)定義模板本例復用前面實例已定義好的模板hello-view.html,內容略。表單提交處理(2)開發表單頁編寫表單頁的源碼如下(hello-submit.html):<html><head><title>我喜愛的編程語言</title></head><body><formaction="/hello"method="post">

言:<inputtype="text"name="language"><br>

戶:<inputtype="text"name="user"><br>

<inputtype="submit"value="確定"></form></body></html>表單提交處理(3)開發后臺程序編寫后臺服務器的程序代碼如下(hello-post.go):(4)運行程序啟動服務器,通過瀏覽器訪問:8080/hello,出現表單頁,在頁面表單中輸入語言和用戶,單擊“確定”按鈕提交,轉到模板頁輸出對該語言的問候,運行過程如圖。提交表單輸出問候第7章Go網絡編程Web開發基礎01Web程序架構模式1.開發視圖2.開發模型和控制器3.運行程序Web程序架構模式傳統網站的Web應用程序普遍采用MVC架構模式,它將軟件系統分為3個基本部分:模型:定義系統所用的數據結構并封裝對數據的處理方法。它可訪問數據庫,有對數據直接操作的權限。視圖:實現Web前端界面,有目的地組織和顯示數據。它只關注數據的樣式和顯示效果而不管其內容的正確性,也不包含處理數據的業務邏輯。控制器:用于控制應用程序的流程、處理與程序業務邏輯相關的數據。它接受客戶端的請求、與模型和視圖交互并做出響應,在系統不同層面間起到組織協調作用。在Go語言開發的Web程序中,用于頁面顯示的模板和模板引擎就是視圖;復用器及其上注冊的諸多處理器一起構成整個系統的控制器部分;而為了存儲數據內容所定義的結構體(類)及其操作數據的方法則是模型。Web程序架構模式一個能完整體現MVC架構的典型Go程序的組成結構如圖。Web程序架構模式【實例7.7】在MySQL數據庫中有一個favlang(愛好語言)表,其中存有一些用戶及各自所喜愛的編程語言名,如圖。Web程序架構模式1.開發視圖(1)定義模板本例依然復用前面實例已定義好的模板hello-view.html,內容略。(2)設計表單頁編寫表單頁的源碼如下(hello-query.html):<html><head><title>我喜愛的編程語言</title></head><body><formaction="/hello"method="post">

戶:<inputtype="text"name="user"><inputtype="submit"value="確定"></form></body></html>Web程序架構模式2.開發模型和控制器本例的模型是一個名為FavLang的結構體(對應數據庫favlang表),它有一個getLang方法可獲取數據庫中給定用戶所喜愛的編程語言名;控制器是一個名為langController的處理器函數。模型和控制器部分的代碼都寫在后臺服務器程序中,如下(hello-mvc.go):3.運行程序啟動服務器,通過瀏覽器訪問:8080/hello,出現表單頁,在頁面表單中輸入用戶名,單擊“確定”按鈕提交,轉到模板頁輸出此用戶對該語言的問候,運行過程如圖。提交表單輸出問候02Gin框架1.安裝Gin框架2.開發視圖3.開發模型和路由引擎4.運行程序Gin框架(1)采用路由引擎實現C(控制器)功能路由引擎(gin.Engine)是Gin提供的一種中間件,乃是整個框架的核心,在用Gin框架編寫的程序一開始就要通過Default方法創建一個路由引擎的實例,它的作用相當于Go語言HTTP程序中的復用器,可通過不同的請求方法將URL關聯到對應的處理器函數,語句如下:路由引擎=gin.Default()路由引擎.方法(URL路徑,函數名)這里的“方法”對應GET、POST、PUT、DELETE等HTTP請求方法,“函數名”是需要由用戶自定義實現的處理器函數。然后,用Run方法啟動路由引擎,相當于開啟ListenAndServe監聽:路

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論