Golang包——net

net/http

一個(gè)簡(jiǎn)單的網(wǎng)絡(luò)請(qǐng)求

func helloWorld(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("hello world"))
}

func main() {
    http.HandleFunc("/hello", helloWorld)
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal(err)
    }
}

請(qǐng)求http://localhost:8080/hello會(huì)打印hello world

go web的請(qǐng)求流程

圖片來(lái)源astaxie的build-web-application-with-golang

go10.1的源碼

func (srv *Server) Serve(l net.Listener) error {
    defer l.Close()
    if fn := testHookServerServe; fn != nil {
        fn(srv, l)
    }
    var tempDelay time.Duration // how long to sleep on accept failure

    if err := srv.setupHTTP2_Serve(); err != nil {
        return err
    }

    srv.trackListener(l, true)
    defer srv.trackListener(l, false)

    baseCtx := context.Background() // base is always background, per Issue 16220
    ctx := context.WithValue(baseCtx, ServerContextKey, srv)
    for {
        rw, e := l.Accept()
        if e != nil {
            select {
            case <-srv.getDoneChan():
                return ErrServerClosed
            default:
            }
            if ne, ok := e.(net.Error); ok && ne.Temporary() {
                if tempDelay == 0 {
                    tempDelay = 5 * time.Millisecond
                } else {
                    tempDelay *= 2
                }
                if max := 1 * time.Second; tempDelay > max {
                    tempDelay = max
                }
                srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay)
                time.Sleep(tempDelay)
                continue
            }
            return e
        }
        tempDelay = 0
        c := srv.newConn(rw)
        c.setState(c.rwc, StateNew) // before Serve can return
        go c.serve(ctx)
    }
}

go c.serve()這里我們可以看到客戶端的每次請(qǐng)求都會(huì)創(chuàng)建一個(gè)Conn懦冰,這個(gè)Conn里面保存了該次請(qǐng)求的信息贞岭,然后再傳遞到對(duì)應(yīng)的handler懈凹,該handler中便可以讀取到相應(yīng)的header信息齿诉,這樣保證了每個(gè)請(qǐng)求的獨(dú)立性。

路由器結(jié)構(gòu)

type ServeMux struct {
    mu    sync.RWMutex
    m     map[string]muxEntry
    es    []muxEntry // slice of entries sorted from longest to shortest.
    hosts bool       // whether any patterns contain hostnames
}

type muxEntry struct {
    h       Handler
    pattern string
}
type Handler interface {
    ServeHTTP(ResponseWriter, *Request)  // 路由實(shí)現(xiàn)器
}

Handler是一個(gè)接口芭概,但是前一小節(jié)中的sayhelloName函數(shù)并沒有實(shí)現(xiàn)ServeHTTP這個(gè)接口,為什么能添加呢?原來(lái)在http包里面還定義了一個(gè)類型HandlerFunc,我們定義的函數(shù)sayhelloName就是這個(gè)HandlerFunc調(diào)用之后的結(jié)果耙饰,這個(gè)類型默認(rèn)就實(shí)現(xiàn)了ServeHTTP這個(gè)接口,即我們調(diào)用了HandlerFunc(f),強(qiáng)制類型轉(zhuǎn)換f成為HandlerFunc類型纹份,這樣f就擁有了ServeHTTP方法苟跪。

GET請(qǐng)求

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    resp, err := http.Get("http://httpbin.org/ip")
    if err != nil {
        fmt.Errorf("%s", err.Error())
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Errorf("%s", err.Error())
        return
    }
    fmt.Println(string(body))
}

自定義request請(qǐng)求

func main() {
    query := map[string]string{"location": "北京",
        "ak": "VAuehGLIw7lW6ovwpnKboM3I", "output": "json"}
    u, _ := url.Parse("http://api.map.baidu.com/telematics/v3/weather")
    q := u.Query()
    for k, v := range query {
        q.Set(k, v)
    }
    u.RawQuery = q.Encode()
    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        fmt.Errorf("%s", err.Error())
        return
    }
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Errorf("%s", err.Error())
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Errorf("%s", err.Error())
        return
    }
    fmt.Println(string(body))
}

Post請(qǐng)求

func main() {
    url := "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
    payload := strings.NewReader("doctype=json&i=好好學(xué)習(xí) 天天向上")
    req, err := http.NewRequest("POST", url, payload)
    if err != nil {
        fmt.Errorf("%s", err.Error())
        return
    }
    req.Header.Add("content-type", "application/x-www-form-urlencoded")

    res, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Errorf("%s", err.Error())
        return
    }
    defer res.Body.Close()
    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Errorf("%s", err.Error())
        return
    }
    fmt.Println(string(body))
}

fasthttp

image.png

http Get請(qǐng)求

import (
    "fmt"
    "github.com/valyala/fasthttp"
    "log"
)

func main() {
    c := fasthttp.Client{}
    statusCode, body, err := c.Get(nil, "http://httpbin.org/ip")
    if statusCode == fasthttp.StatusOK {
        fmt.Println(string(body))
    } else {
        log.Fatalf("%d:%s", statusCode, err.Error())
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蔓涧,隨后出現(xiàn)的幾起案子件已,更是在濱河造成了極大的恐慌,老刑警劉巖元暴,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篷扩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡茉盏,警方通過(guò)查閱死者的電腦和手機(jī)鉴未,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)援岩,“玉大人歼狼,你說(shuō)我怎么就攤上這事∠砘常” “怎么了羽峰?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)添瓷。 經(jīng)常有香客問(wèn)我梅屉,道長(zhǎng),這世上最難降的妖魔是什么鳞贷? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任坯汤,我火速辦了婚禮,結(jié)果婚禮上搀愧,老公的妹妹穿的比我還像新娘惰聂。我一直安慰自己,他們只是感情好咱筛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布搓幌。 她就那樣靜靜地躺著,像睡著了一般迅箩。 火紅的嫁衣襯著肌膚如雪溉愁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天饲趋,我揣著相機(jī)與錄音拐揭,去河邊找鬼撤蟆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛堂污,可吹牛的內(nèi)容都是我干的家肯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼敷鸦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼息楔!你這毒婦竟也來(lái)了寝贡?” 一聲冷哼從身側(cè)響起扒披,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎圃泡,沒想到半個(gè)月后碟案,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颇蜡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年价说,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片风秤。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鳖目,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缤弦,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布岁钓,位于F島的核電站激涤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏累提。R本人自食惡果不足惜尘喝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望斋陪。 院中可真熱鬧朽褪,春花似錦、人聲如沸无虚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)骑科。三九已至橡淑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咆爽,已是汗流浹背梁棠。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工置森, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人符糊。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓凫海,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親男娄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子行贪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容