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