网络传输存在的一个问题是,当消息发送速度非常快(比如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,那么后面的就会覆盖前面的长度。
又回到根本性的问题:填充数据与取数据的队列长度 不一致。
。。。下班,明天再来想。