記一次關于content-length有意思的排查

一鸯隅、 項目背景

? ? ?一個物聯(lián)網(wǎng)項目,公司要求降低硬件成本磅摹,真可謂窮公司練技術滋迈,硬件資源有限制霎奢,最終技術選型使用單片機户誓,因資源受限,硬件sdk中沒有現(xiàn)成的http可使用幕侠,因此帝美,最終嵌軟同學直接在TCP socket基礎上,構造了Http請求頭晤硕,仿造http與物聯(lián)網(wǎng)平臺進行交互悼潭。

? ? 因此庇忌,有意思的事情發(fā)生了,嵌軟同學仿造http的過程如下:

1舰褪、初始化tcp client皆疹,然后構造http請求,通過tcp send發(fā)送http請求占拍,接著recv等待對端的返回略就;

2、收到recv報文之后晃酒,讀取整個response報文表牢,然后轉化為string,從string中匹配content-length字段贝次,從而獲取response的body體大小崔兴。

看似一切正常,而且嵌軟同學之前也這么做過蛔翅,為啥這次就不行了那敲茄,一切都是chunk(這里就不解釋啥是chunk了,不知的同學自行百度吧)搞的鬼山析,有的時候server會使用chunk方式進行數(shù)據(jù)返回折汞,chunk模式下,是可以不存在content-length字段的(嚴格上來說是沒有content-length)盖腿,因此這種情況下爽待,按照上面的流程就跑不通了。

二翩腐、content-length和chunk是如何工作的鸟款?

? ? 這里百度了一些文章,說是chunk和gzip有關茂卦,但是百思不得其解何什,沒有縷出來兩者的關聯(lián)關系,實驗了一些demo等龙,請求和返回頭里都含有gzip的壓縮方式处渣,但是content-lenght字段還是存在,所以蛛砰,索性認為沒有必然聯(lián)系罐栈。

? ? 再繼續(xù)百度了下,說是chunk和keep-alive相關泥畅,看到這我想是因為http1.1支持了連接服用荠诬,因此才支持了chunk,但是并不是說一旦開啟了keep-alive所有交互都是chunk模式,事實自己也寫了個小demo試了下柑贞,確實如此方椎。

?繼續(xù)百度之旅,最后看到chunk和flush函數(shù)有關钧嘶,正常我們server端在返回數(shù)據(jù)的時候棠众,是使用write函數(shù),而write函數(shù)并不是直接給用戶返回數(shù)據(jù)有决,而是先降數(shù)據(jù)寫回緩沖區(qū)摄欲,直到連接close之前,會先將緩沖區(qū)的數(shù)據(jù)buffer發(fā)送過去疮薇,然后close連接胸墙。而flash函數(shù)則是手動將緩沖區(qū)的數(shù)據(jù)發(fā)送到客戶端,然后server端可以繼續(xù)將數(shù)據(jù)寫到緩沖區(qū)按咒,然后再調用flush函數(shù)迟隅,而還是之前的那一個連接(我想這也是之前百度到的一些文章說chunk和keepalive有關的原因吧),這樣收到的傳輸方式就是chunk的方式励七。而我們調用write函數(shù)智袭,然后等到hander結束,close連接之前發(fā)送數(shù)據(jù)這個流程掠抬,也就是我們說的非chunk方式吧(除buff中數(shù)據(jù)超過buff大小的情況)吼野。

三、demo驗證

? ? 這里采用golang代碼進行了過程驗證两波。

1瞳步、使用gin router寫了一個簡單的請求,如下:

????r :=gin.Default()

????r.GET("/ping", func(c *gin.Context) {

????????c.JSON(200, gin.H{

????????????"message":"pong",

? ? ????? })

})

r.Run()

請求結果如下所示:

2腰奋、修改flush發(fā)送數(shù)據(jù)方式单起,如下:

????r :=gin.Default()

????r.GET("/ping", func(c *gin.Context) {

????w := c.Writer

????flusher, ok := w.(http.Flusher)

? ? if !ok {

????????panic("expected http.ResponseWriter to be an http.Flusher")

????}

????fmt.Fprintf(w,string("hello chunk!"))

????flusher.Flush()

? ?})

r.Run()

結果如下圖:

四、總結

? ?1劣坊、通過理論+實驗來看嘀倒,chunk和keepalive有關系,chunk是基于keekalive基礎實現(xiàn)的局冰,但是他們倆者之間并不是必然的關系测蘑。

? ? 2、server端如果不想采取chunk方式回復數(shù)據(jù)康二,以免有些客戶端對chunk支持性不好碳胳,通過server端可以對傳輸方式進行控制,比如通過避免使用flush函數(shù)回復數(shù)據(jù)的方式赠摇。

? ? 3固逗、至于其他語言例如java如何控制傳輸方式浅蚪,后面我們再完善補充藕帜,多謝烫罩。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市洽故,隨后出現(xiàn)的幾起案子贝攒,更是在濱河造成了極大的恐慌,老刑警劉巖时甚,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隘弊,死亡現(xiàn)場離奇詭異,居然都是意外死亡荒适,警方通過查閱死者的電腦和手機梨熙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刀诬,“玉大人咽扇,你說我怎么就攤上這事∩乱迹” “怎么了质欲?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長糠馆。 經常有香客問我嘶伟,道長,這世上最難降的妖魔是什么又碌? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任九昧,我火速辦了婚禮,結果婚禮上毕匀,老公的妹妹穿的比我還像新娘耽装。我一直安慰自己,他們只是感情好期揪,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布掉奄。 她就那樣靜靜地躺著,像睡著了一般凤薛。 火紅的嫁衣襯著肌膚如雪姓建。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天缤苫,我揣著相機與錄音速兔,去河邊找鬼。 笑死活玲,一個胖子當著我的面吹牛涣狗,可吹牛的內容都是我干的谍婉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼镀钓,長吁一口氣:“原來是場噩夢啊……” “哼穗熬!你這毒婦竟也來了?” 一聲冷哼從身側響起丁溅,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤唤蔗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后窟赏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妓柜,經...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年涯穷,在試婚紗的時候發(fā)現(xiàn)自己被綠了棍掐。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡拷况,死狀恐怖作煌,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情蝠嘉,我是刑警寧澤最疆,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站蚤告,受9級特大地震影響努酸,放射性物質發(fā)生泄漏。R本人自食惡果不足惜杜恰,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一获诈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧心褐,春花似錦舔涎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掘而,卻和暖如春挟冠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背袍睡。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工知染, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人斑胜。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓控淡,卻偏偏與公主長得像嫌吠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子掺炭,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內容