網路傳輸存在的一個問題是,當訊息發送速度非常快(比如1s發送200個資料包)時,緩衝區可能會填滿而導致發送隊列後面的資料發送失敗
因此試圖通過建立可變緩衝區當資料發送速度非常快時,馬上擴充緩衝區容量,使其適應資料的發送數率
通過動態數組來實現一個動態迴圈隊列的資料緩衝區
std::vector<DataItem> *_dataQueue;
調試中發現一個問題,就是從緩衝區取出的資料次序與送入次數不一致性
原因:首先往緩衝區依次填入資料資料包所在位置依次為:
前面的表示緩衝區的位置(為方便,從1開始計數),括弧裡表示發送包的編號
1(1) 2(2) 3(3) 4(4) 5(5) 6(6) 7(7) 8(8)
此時另外一個線程取出資料包1(1) 2(2) 3(3)發送;
發送完畢後會停止一段時間
此時迴圈隊列位置Position = 4
發送線程繼續塞入資料,會先填充位置123,
緩衝區已滿緩衝區資料依次為: 1(9) 2(10) 3(11) 4(4) 5(5) 6(6) 7(7) 8(8)
於是將緩衝區容量由8擴充至12
繼續發送資料
依次填充位置9(12) 10(13) 11(14) 12(15)
填充完畢後,開始取資料由於迴圈隊列位置Position = 4
那麼,此時取資料的順序變為: 4(4) 5(5) 6(6) 7(7) 8(8) 9(12) 10(13) 11(14) 12(15) 1(9) 2(10) 3(11)
而送入緩衝區的資料包次數為: 4(4) 5(5) 6(6) 7(7) 8(8) 1(9) 2(10) 3(11) 9(12) 10(13) 11(14) 12(15)
兩者不一致。
根本原因是:
填充資料時是以長度為8的隊列在迴圈,但是取資料的時候則是以一個長度為12的迴圈隊列取資料,次序自然不能保證了。
考慮方法:
1.在擴充容量過程中,將position標號前面的資料包依次拷入擴容的空間,使其與填入緩衝區次序一次。 也就是在擴容的時候
將緩衝區中的資料做一次部分移動:
移動前: 1(9) 2(10) 3(11) 4(4) 5(5) 6(6) 7(7) 8(8)
移動後: 1(-1) 2(-1) 3(-1) 4(4) 5(5) 6(6) 7(7) 8(8) 9(9) 10(10) 11(11) 12(-1)
(括弧裡-1表示資料包無效,可以繼續放入資料) 嘗試了:速度太慢
2。記錄前一次一個緩衝區的大小,先做小隊列迴圈,再做大隊列迴圈。比如說由8擴充至12時,先做一個隊列為8的迴圈,再做一個隊列長為12的迴圈。
問題是,如果資料速率超快,那麼隊列長度的變化由8,12,16,32,那麼後面的就會覆蓋前面的長度。
又回到根本性的問題:填充資料與取資料的隊列長度 不一致。
。。。下班,明天再來想。