什么是TCP協(xié)議娘摔?
TCP(Transmission Control Protocol傳輸控制協(xié)議)是Internet協(xié)議組的主要協(xié)議之一。起源于初始的網(wǎng)絡(luò)實現(xiàn)户魏,補(bǔ)充了IP協(xié)議综膀。因此通常稱為TCP/IP協(xié)議。TCP在運(yùn)行在IP通信網(wǎng)絡(luò)的應(yīng)用程序之間提供穩(wěn)定的蛾洛、有序的和錯誤檢查的8字節(jié)流分發(fā)功能⊙丬剑—— from wiki
什么是TCP的粘包和拆包問題轧膘?
TCP是一個“流”協(xié)議,所謂流兔甘,就是沒有邊界的一串?dāng)?shù)據(jù)谎碍。TCP底層不了解業(yè)務(wù)數(shù)據(jù)的含義,只是按照緩沖區(qū)的情況進(jìn)行包的劃分洞焙,那么業(yè)務(wù)上一個完整的數(shù)據(jù)包有可能被劃分成多個包發(fā)出蟆淀,也可能多個包被合并成一個數(shù)據(jù)包發(fā)出,這就是TCP的粘包和拆包問題澡匪。
如何解決粘包和拆包問題熔任?
TCP不知道數(shù)據(jù)包的業(yè)務(wù)含義,所以只能通過上層協(xié)議棧的設(shè)計來結(jié)局唁情,主流方案:
定長消息疑苔,消息長度是固定的,不夠的進(jìn)行補(bǔ)齊
特殊字符分隔甸鸟,如FTP協(xié)議在包尾添加換行符進(jìn)行分隔
將消息分為消息投和消息體惦费,消息頭中包含消息的總長,如前4個字節(jié)表示整個消息的長度(最靈活和常用的方案)
Netty對粘包和拆包問題的處理
Netty對解決粘包和拆包的方案做了抽象抢韭,提供了一些解碼器(Decoder)來解決粘包和拆包的問題薪贫。如:
LineBasedFrameDecoder:以行為單位進(jìn)行數(shù)據(jù)包的解碼
DelimiterBasedFrameDecoder:以特殊的符號作為分隔來進(jìn)行數(shù)據(jù)包的解碼
FixedLengthFrameDecoder:以固定長度進(jìn)行數(shù)據(jù)包的解碼
LenghtFieldBasedFrameDecode:適用于消息頭包含消息長度的協(xié)議(最常用)
所以對使用Netty進(jìn)行網(wǎng)絡(luò)讀寫的程序,可以直接使用這些Decoder來完成數(shù)據(jù)包的解碼刻恭。
由于業(yè)務(wù)程序的復(fù)雜性瞧省,可能協(xié)議也非常復(fù)雜。對于高并發(fā)吠各、大流量的系統(tǒng)來說臀突,每個數(shù)據(jù)包都不應(yīng)該傳輸多余的數(shù)據(jù)(所以補(bǔ)齊的方式肯定不可让阕ァ)贾漏,LenghtFieldBasedFrameDecode更適合這樣的場景。
LenghtFieldBasedFrameDecode提供了靈活的配置來支持業(yè)務(wù)消息的解碼:
實際生產(chǎn)環(huán)境中更多是采用自定義的協(xié)議藕筋,并且編寫自己的Decoder類(一般繼承LenghtFieldBasedFrameDecode)來完成業(yè)務(wù)包的解碼纵散。