關(guān)于使用不可靠的UDP實(shí)現(xiàn)可靠傳輸
整理本Log希望日后有時(shí)間可以實(shí)現(xiàn)定制化的UDP協(xié)議,很多情況即想要UDP的部分特性,又希望UDP在接受范圍內(nèi)盡量穩(wěn)定,如果可以實(shí)現(xiàn)一個(gè)相對(duì)通用的類庫實(shí)現(xiàn)此類需求將大大簡(jiǎn)化。(重復(fù)造輪子)
以下是常見的保證UDP傳輸穩(wěn)定手段,可以根據(jù)需求自行選擇實(shí)現(xiàn)部分,全部實(shí)現(xiàn)就相當(dāng)于在應(yīng)用層重新實(shí)現(xiàn)一遍TCP。
1、超時(shí)重傳
2、有序接受
3、應(yīng)答確認(rèn)
4、滑動(dòng)窗口流量控制
(一)發(fā)送機(jī)制
首先來設(shè)計(jì)最為重要的可靠性。在UDP增加報(bào)頭前,我們先定義8個(gè)字節(jié)的協(xié)議頭,為2個(gè)字節(jié)的數(shù)據(jù)包標(biāo)識(shí),2個(gè)字節(jié)的發(fā)送序號(hào),2個(gè)字節(jié)的文件指針定位和2個(gè)字節(jié)的數(shù)據(jù)包中數(shù)據(jù)大小信息。數(shù)據(jù)包標(biāo)志指明該數(shù)據(jù)包為文件數(shù)據(jù)包、確認(rèn)包或者其它控制包,發(fā)送序號(hào)用來指明數(shù)據(jù)包的順序信息,指針定位字節(jié)數(shù)據(jù)用來指明該數(shù)據(jù)包中數(shù)據(jù)被填寫到文件的哪個(gè)位置,最后的大小信息也是用來向文件中讀寫數(shù)據(jù)時(shí)使用。
發(fā)送大致流程:
這里我考慮的是:繼承QUdpSocket,重新實(shí)現(xiàn)write接口。這里兩種情況,簡(jiǎn)單情況下盡量只讓接收方發(fā)送一次錯(cuò)誤信息回發(fā)送方,不做重傳。復(fù)雜情況則每個(gè)分包都需要接收方返回確認(rèn)接收信息,如未收到則重新發(fā)送
int writeMessage(MessageType type,QString data)
{
head = type?+ sendNumber + packgeNumber + dataSize
//type指明發(fā)送數(shù)據(jù)類型文件還是信息
//sendNumber用于數(shù)據(jù)被分為幾個(gè)小包
//packgeNumber當(dāng)前是第幾個(gè)包
//dataSize信息大小
write head+data
}
(二)接收機(jī)制
1、簡(jiǎn)單情況下:
接收端收到全部數(shù)據(jù)包和結(jié)束包后,按照包頭錯(cuò)序重排,接受過程只要保證序號(hào)從小到大即可,反之不是則出現(xiàn)錯(cuò)誤。
2、高可靠情況下:
文件信息包被接收端接受以后使用確認(rèn)機(jī)制確定是否接受這個(gè)文件,并把決定回饋給發(fā)送端。此時(shí),發(fā)送端如果收到的是“確定接受”的結(jié)果,將會(huì)把這個(gè)文件的整組數(shù)據(jù)報(bào)全部發(fā)送過去。
這里我們不像最傳統(tǒng)的可靠傳輸協(xié)議TCP協(xié)議一樣,對(duì)于每個(gè)每個(gè)報(bào)文都要確認(rèn)接受完才會(huì)對(duì)下一個(gè)報(bào)文進(jìn)行處理。接受端在接受這組報(bào)文的時(shí)候?qū)⒆袷劐e(cuò)序重排機(jī)制,接受過程只要保證序號(hào)從小到大即可,反之不是則出現(xiàn)錯(cuò)誤,向發(fā)送端回復(fù)錯(cuò)誤包序號(hào)。
發(fā)送端發(fā)完所有報(bào)文延遲一點(diǎn)時(shí)間再發(fā)送一個(gè)結(jié)束報(bào)文,延遲時(shí)間是為了減少結(jié)束報(bào)文比數(shù)據(jù)報(bào)文還早被接受的情況,當(dāng)然即使這種情況出現(xiàn)也不會(huì)破壞可靠性,只不過在在結(jié)束報(bào)文之后的數(shù)據(jù)報(bào)文會(huì)被當(dāng)做丟失的包被要求重發(fā),降低效率。接受端接受到結(jié)束報(bào)文后按照一開始的文件信息包的信息和序列號(hào)做對(duì)比,把沒有的序列號(hào)的報(bào)文的信息傳回給發(fā)送端,要求重新發(fā)送這些報(bào)文。發(fā)送端接到信息以后重發(fā)丟失的數(shù)據(jù)包。直到接收端拿到的報(bào)文和信息匹配,接受端就可以發(fā)回一個(gè)“接受完畢”的報(bào)文。這樣發(fā)送端接受端再進(jìn)行下一次文件傳輸。
具體自動(dòng)重發(fā)機(jī)制、請(qǐng)求重發(fā)機(jī)制、確認(rèn)機(jī)制日后實(shí)際實(shí)現(xiàn)時(shí)補(bǔ)充。