TCP傳輸協(xié)議中如何解決丟包問題?
當(dāng)TCP在不可靠的網(wǎng)絡(luò)上實(shí)現(xiàn)可靠傳輸時(shí),必然會(huì)有丟包。TCP是一個(gè)"流媒體"協(xié)議。一個(gè)詳細(xì)的包會(huì)被TCP拆分成幾個(gè)包進(jìn)行上傳,小的包會(huì)被打包成大的上傳,也就是說TCP會(huì)對(duì)包進(jìn)行粘貼和解包。
但是很多人有不同的理解。TCP協(xié)議本身確保傳輸?shù)臄?shù)據(jù)不會(huì)丟失其完整性。如果在傳輸過程中發(fā)現(xiàn)數(shù)據(jù)丟失或丟包,最大的可能是在發(fā)送或接收節(jié)目的過程中出現(xiàn)了問題。
比如服務(wù)器向客戶端發(fā)送大量數(shù)據(jù),發(fā)送頻率很高,所以在發(fā)送環(huán)節(jié)很可能出現(xiàn)錯(cuò)誤(1。程序處理中的邏輯錯(cuò)誤;2.多線程同步問題;3.緩沖區(qū)溢出等。)如果不處理發(fā)送失敗,客戶端接收到的數(shù)據(jù)會(huì)小于理論數(shù)據(jù),導(dǎo)致數(shù)據(jù)丟失和丟包。這個(gè)現(xiàn)象,其實(shí)本質(zhì)上并不是丟包或者數(shù)據(jù)丟失。只是因?yàn)槌绦蛱幚礤e(cuò)誤,導(dǎo)致部分?jǐn)?shù)據(jù)無法通過socket成功發(fā)送出去。
關(guān)于發(fā)送功能的問題:
首先,你必須清楚send函數(shù)是做什么的。不管他是把數(shù)據(jù)傳到本地TCP層還是應(yīng)用層,確認(rèn)接收方的TCP層然后返回。后一種情況,你是對(duì)的,其實(shí)不是。那個(gè)因?yàn)閚agle算法可以t被使用,即算法將send函數(shù)收到的小數(shù)據(jù)匯總成大數(shù)據(jù)包發(fā)送出去。
即使發(fā)送功能可以發(fā)送數(shù)據(jù),對(duì)方也不一定能接受。TCP協(xié)議只在傳輸層履行義務(wù),send函數(shù)在應(yīng)用層只起到向TCP層傳輸數(shù)據(jù)的作用,與TCP層無關(guān)。
常見的解決方案包括解包、添加包頭和發(fā)送組合包。如果服務(wù)器或客戶端斷開連接,通常會(huì)使用心跳測(cè)試。
心跳測(cè)試:定期向服務(wù)器發(fā)送數(shù)據(jù)包。為了節(jié)省資源,通常會(huì)發(fā)送空包。如果發(fā)送失敗表明套接字已經(jīng)斷開,則需要根據(jù)具體情況釋放資源并重新連接。
TCP傳輸可以保證數(shù)據(jù)交換的可靠性,也就是說一臺(tái)主機(jī)向目標(biāo)計(jì)算機(jī)正確傳輸數(shù)據(jù),目標(biāo)計(jì)算機(jī)的協(xié)議棧有一定的限制。如果目標(biāo)計(jì)算機(jī)上收到的數(shù)據(jù)沒有及時(shí)處理,堆棧就會(huì)溢出。
這個(gè)溢出不是TCP協(xié)議本身造成的,而是系統(tǒng)IP協(xié)議棧的緩沖區(qū)溢出造成的!