日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

go语言服务器运行,Go语言实现Web服务器

發布時間:2023/12/2 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 go语言服务器运行,Go语言实现Web服务器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

使用Go語言的庫非常容易實現一個Web服務器,用來響應像fetch那樣的客戶端請求。本節將展示一個迷你服務器,返回訪問服務器的URL的路徑部分。例如,如果請求的URL是http://localhost:8000/hello,響應將是URL.Path="/hello"。

//server1.go這是一個迷你回聲服務器packagemainimport("fmt""log""net/http")funcmain(){http.HandleFunc("/",handler)//回聲請求調用處理程序log.Fatal(http.ListenAndServe("localhost:8000",nil))}//處理程序回顯請求URLr的路徑部分funchandler(whttp.ResponseWriter,r*http.Request){fmt.Fprintf(w,"URL.Path=%qn",r.URL.Path)}

這個程序只有寥寥幾行代碼,因為庫函數做了大部分工作。main函數將一個處理函數和以“/”開頭的URL鏈接在一起,代表所有的URL使用這個函數處理,然后啟動服務器監聽進入8000端口處的請求。

一個請求由一個http.Request類型的結構體表示,它包含很多關聯的域,其中一個是所請求的URL。當一個請求到達時,它被轉交給處理函數,并從請求的URL中提取路徑部分(/hello),使用fmt.Printf格式化,然后作為響應發送回去。

讓我們在后臺啟動服務器。在MacOSX或者Linux上,在命令行后添加一個&符號;在微軟Windows上,不需要&符號,而需要單獨開啟一個獨立的命令行窗口。

$gorunsrc/gopl.io/chl/serverl/main.go&

可以從命令行發起客戶請求:

$gobuildgopl.io/ch5/fetch

$./fetchhttp://localhost:8000

URL.Path=T

$./fetchhttp://localhost:8000/help

URL.Path="/help"

另外,還可以通過瀏覽器進行訪問,如下圖所示。

圖:來自回聲服務器的響應

為服務器添加功能很容易。一個有用的擴展是一個特定的URL,它返回某種排序的狀態。例如,這個版本的程序完成和回聲服務器一樣的事情,但同時返回請求的數量;URL/count請求返回到現在為止的個數,去掉/count請求本身:

//server2.go這是一個迷你的回聲和計數器服務器packagemainimport("fmt""log""net/http""sync")varmusync.Mutexvarcountintfuncmain(){http.HandleFunc("/",handler)http.HandleFunc("/count",counter)log.Fatal(http.ListenAndServe("localhost:8000",nil))}//處理程序回顯請求的URL的路徑部分funchandler(whttp.ResponseWriter,r*http.Request){mu.Lock()count++mu.Unlock()fmt.Fprintf(w,"URL.Path=%qn",r.URL.Path)}//counter回顯目前為止調用的次數funccounter(whttp.ResponseWriter,r*http.Request){mu.Lock()fmt.Fprintf(w,"Count%dn",count)mu.Unlock()}

這個服務器有兩個處理函數,通過請求的URL來決定哪一個被調用:請求/count調用counter,其他的調用handler。以“/”結尾的處理模式匹配所有含有這個前綴的URL。在后臺,對于每個傳入的請求,服務器在不同的goroutine中運行該處理函數,這樣它可以同時處理多個請求。

然而,如果兩個并發的請求試圖同時更新計數值count,它可能會不一致地增加,程序會產生一個嚴重的競態bug。為避免該問題,必須確保最多只有一個goroutine在同一時間訪問變量,這正是mu.Lock()和mu.Unlock()語句的作用。

作為一個更完整的例子,處理函數可以報告它接收到的消息頭和表單數據,這樣可以方便服務器審查和調試請求:

//處理程序回顯HTTP請求funchandler(whttp.ResponseWriter,r*http.Request){fmt.Fprintf(w,"%s%s%sn",r.Method,r.URL,r.Proto)fork,v:=ranger.Header{fmt.Fprintf(w,"Header[%q]=%qn",k,v)}fmt.Fprintf(w,"Host=%qn",r.Host)fmt.Fprintf(w,"RemoteAddr=%qn",r.RemoteAddr)iferr:=r.ParseForm();err!=nil{log.Print(err)}fork,v:=ranger.Form{fmt.Fprintf(w,"Form[%q]=%qn",k,v)}}

這里使用http.Request結構體的成員來產生類似下面的輸出:

GET/?q=queryHTTP/1.1

Header["Accept-Encoding"]=["gzip,deflate,sdch"]

Header["Accept-Language"]=["en-US,en;q=0.8"]

Header["Connection"]=["keep-alive"]

Header["Accept"]=["text/html,application/xhtml+xml,application/xml;…"]

Header["User-Agent"]=["Mozilla/5.0(Macintosh;IntelMacOSX10_7_5)…"]

Host="localhost:8000"

RemoteAddr="127.0.0.1:59911"

Form["q"]=["query"]

注意這里是如何在if語句中嵌套調用ParseForm的。Go允許一個簡單的語句(如一個局部變量聲明)跟在if條件的前面,這在錯誤處理的時候特別有用。也可以這樣寫:

err:=r.ParseForm()

iferr!=nil{

log.Print(err)

}

這些程序中,我們看到了作為輸出流的三種非常不同的類型。fetch程序復制HTTP響應到文件os.Stdout,像lissajous一樣;fetchall程序通過將響應復制到ioutil.Discard中進行丟棄(在統計其長度時);Web服務器使fmt.Fprintf通過寫入http.Responsewriter來讓瀏覽器顯示。

盡管三種類型細節不同,但都滿足一個通用的接口(interface),該接口允許它們按需使用任何一種輸出流。該接口稱為io.Writer。

我們來看一下整合Web服務器和lissajous函數是一件多么容易的事情,這樣GIF動畫將不再輸出到標準輸出而是HTTP客戶端。簡單添加這些行到Web服務器:

handler:=func(whttp.ResponseWriter,r*http.Request){

lissajous(w)

}

http.HandleFunc("/",handler)

或者也可以:

http.HandleFunc("/",func(whttp.ResponseWriter,r*http.Request){

lissajous(w)

})

上面HandleFunc函數中立即調用的第二個參數是函數字面量,這是一個在該場景中使用它時才定義的匿名函數。

一旦完成這個改變,就可以通過瀏覽器訪問http://localhost:8000。每次加載頁面,將看到一個類似下圖的動畫。

圖:瀏覽器中的動態利薩茹圖形

總結

以上是生活随笔為你收集整理的go语言服务器运行,Go语言实现Web服务器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。