2021-02-01 分類(lèi): 網(wǎng)站建設(shè)
作為一個(gè)程序猿,對(duì)造輪子這事情可以說(shuō)是情有獨(dú)鐘,幾乎
上面每一條都涉及好多輪子,每一個(gè)都是精通,如果真能做到。那這個(gè)人可以說(shuō)是碼農(nóng)中的戰(zhàn)斗機(jī)。
那我們現(xiàn)在目標(biāo)就是去做這個(gè)戰(zhàn)斗機(jī)。而這個(gè)方法,就是自己去造輪子,造的目的不是為了在項(xiàng)目中使用自己造的輪子,而是為了去了解輪子的構(gòu)造,然后自己動(dòng)手去體會(huì)造輪子的過(guò)程。
本文主要講http協(xié)議。
正文分割線
我們都知道http是基于tcp之上的,那我們現(xiàn)在就自己基于tcp來(lái)實(shí)現(xiàn)一個(gè)最小的http服務(wù),功能非常簡(jiǎn)單:
先來(lái)看請(qǐng)求格式:
http的報(bào)文大概分為3部分:
此處請(qǐng)求行是格式是固定的,
先寫(xiě)代碼來(lái)看看的:
可以看到我們讀取的到數(shù)據(jù)是如上,我們可以看到格式上是符合的。
Ps:上面這個(gè)代碼有個(gè)小問(wèn)題,因?yàn)閠cp連接是字節(jié)流的,我們通過(guò)readAll方法從連接中讀取數(shù)據(jù)的是,只要瀏覽器上不主動(dòng)斷開(kāi),會(huì)一直阻塞在readaALL上。。。
上面我們將收到的數(shù)據(jù)稍微整理下
上面首部中Content-length: 0可以說(shuō)是非常關(guān)鍵,他告訴了我們應(yīng)該要在兩個(gè) 后繼續(xù)讀取多少字節(jié)。
下面我們開(kāi)始來(lái)寫(xiě)解析代碼,先是解析文件頭
然后我們?cè)俳馕鍪撞?/p>
解析完后,我們?cè)趯?xiě)返回值,返回報(bào)文的格式放下:
下面是返回值的代碼:
完整的例子可以看GitHub上代碼,歡迎star
https://github.com/zhuanxuhit/go-in-practice/tree/master/wheel/http/v1
我們有了第一版http輪子后,我們能和前面介紹的輪子系列:rpc聯(lián)系起來(lái),在rpc系列中,我們講了設(shè)計(jì)通信協(xié)議來(lái)傳遞消息,此處http是通過(guò)頭部的url+method的方法來(lái)表示我要調(diào)用服務(wù)端哪個(gè)方法,然后分割符是使用 ,連續(xù)兩個(gè) 表示后續(xù)是消息體,為了高速我們消息體的大小和格式,在header中必須指明content-type和content-length,這些都是在我們?cè)趯?shí)現(xiàn)http協(xié)議的時(shí)候遵循的。
那現(xiàn)在寫(xiě)完最初版代碼,我們回過(guò)頭總結(jié)下我們之前做的rpc輪子,數(shù)據(jù)編碼采用了protobuf,然后基于tcp自己定義了一套消息協(xié)議,其實(shí)做的事情跟http/1.1是一樣的,我們完全可以在http通信的時(shí)候,將content-type設(shè)置為protobuf,然后通信雙方雙方能夠編解碼即可。
在實(shí)現(xiàn)過(guò)程中,我們發(fā)現(xiàn)如果用http1.1作為通信協(xié)議,有什么問(wèn)題呢?
那上面這兩點(diǎn)都是要解決的問(wèn)題,在http2.0中都有相應(yīng)的方案
那怎么能做到一個(gè)連接同時(shí)發(fā)起多個(gè)請(qǐng)求呢?通信雙方就必須對(duì)每個(gè)請(qǐng)求進(jìn)行編碼,這樣不同的響應(yīng)就能和請(qǐng)求對(duì)應(yīng)上了。
具體可以看兩張圖:
HTTP 2.0 其實(shí)是將三個(gè)請(qǐng)求變成三個(gè)流,將數(shù)據(jù)分成幀,亂序發(fā)送到一個(gè)tcp連接中
通過(guò)stream對(duì)不同請(qǐng)求進(jìn)行區(qū)分,然后在將一個(gè)消息拆分為多個(gè)幀進(jìn)行發(fā)送。
那http2.0后,還能不能更快了呢?于是就有了QUIC協(xié)議,這個(gè)協(xié)議肯定是為了解決http2.0的某些問(wèn)題的。
重傳有個(gè)測(cè)不準(zhǔn)問(wèn)題,左邊是1.1,我們發(fā)現(xiàn)重發(fā)100編號(hào)的時(shí)候,如果后續(xù)收到應(yīng)答101,我們不知道這個(gè)是針對(duì)第一次100的應(yīng)答還是第二次重傳100的應(yīng)答,http2.0則定義了每次發(fā)送數(shù)據(jù),編號(hào)都需要增加,然后通過(guò)offset來(lái)標(biāo)明數(shù)據(jù)的前后續(xù)關(guān)系。
首先本文基于tcp自己實(shí)現(xiàn)了http1.1的協(xié)議,實(shí)現(xiàn)中發(fā)現(xiàn)這個(gè)通信協(xié)議和我們之前輪子系列文章rpc都是消息協(xié)議,只是對(duì)消息體的編碼格式不同而已。
接著我們?cè)谧约簩?xiě)的過(guò)程中發(fā)現(xiàn)了http1.1的種種問(wèn)題,針對(duì)這些問(wèn)題有了http2.0,繼而又有了QUIC。
本文名稱(chēng):帶你手?jǐn)]一個(gè)http服務(wù)器(帶源碼)
網(wǎng)站路徑:http://www.rwnh.cn/news/98659.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、移動(dòng)網(wǎng)站建設(shè)、App開(kāi)發(fā)、網(wǎng)站收錄、搜索引擎優(yōu)化、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容