版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第c++實現(xiàn)一個簡易的網(wǎng)絡緩沖區(qū)的實踐size_tused_size=m_write_index-m_read_index;//used_size表示已經(jīng)存儲的字節(jié)數(shù)
size_tremain_size=m_max_size-used_size;//remain_size表示剩余空間
size_texpand_size=m_max_size;
while(remain_sizeneed_size){//剩余空間不夠時擴展,用while表示直到擴展至夠用
expand_size*=m_expand_par;
remain_size=expand_size-used_size;
//cout"擴展長度中...總剩余總長度"remain_size""expand_sizeendl;
char*s1=newchar[expand_size]();//申請新的空間
memcpy(s1,m_s,m_max_size);
free(m_s);
m_s=s1;//將新空間掛載到緩沖區(qū)
m_max_size=expand_size;//更新緩沖區(qū)總長度
//cout"擴展結(jié)束,總長度為"m_max_sizeendl;
3.外部接口設計與實現(xiàn)
以讀緩沖區(qū)為例需要提供的接口有:向緩沖區(qū)寫入數(shù)據(jù)write_to_buffer(),向緩沖區(qū)讀取數(shù)據(jù)read_from_buffer(),得到能夠讀取的最大字節(jié)數(shù)readable_bytes()。
classBuffer{
public:
voidwrite_to_buffer(char*src);//從src中寫數(shù)據(jù)
size_treadable_bytes();//存儲數(shù)據(jù)的字節(jié)數(shù)
size_tread_from_buffer(char*dst,intbytes);//讀數(shù)據(jù)
size_tpop_bytes(size_tbytes);//丟棄數(shù)據(jù)
①寫入緩沖區(qū)write_to_buffer()
write_to_buffer()實現(xiàn)的思路如流程圖所示:
判斷剩余空間:
剩余空間不夠:調(diào)整數(shù)據(jù)至頭部、擴展緩沖區(qū)
剩余空間足夠:向下繼續(xù)
判斷當前空間:
當前空間不夠:調(diào)整數(shù)據(jù)至頭部
剩余空間足夠:向下繼續(xù)
存儲數(shù)據(jù)
根據(jù)流程圖實現(xiàn)起來邏輯非常清晰,src表示原始數(shù)據(jù)
voidBuffer::write_to_buffer(char*src)
size_tused_size=m_write_index-m_read_index;//used_size表示已經(jīng)存儲的字節(jié)數(shù)
size_tremain_size=m_max_size-used_size;//remain_size表示剩余空間
size_tcur_size=m_max_size-m_write_index;//cur_size表示當前能夠存儲的空間
size_tsize=init_random_write(src);
//printf("已經(jīng)使用%d,剩余總長度%d,剩余當前長度%d\n",used_size,remain_size,cur_size);
if(sizeremain_size){//剩余空間不夠
adjust_buffer();
expand_buffer(size);
elseif(sizecur_size){//剩余空間夠,當前存不下
adjust_buffer();
memcpy(m_s[m_write_index],src,size);//存儲數(shù)據(jù)
m_write_index+=size;
delete[]src;
//更新并打印log
//used_size=m_write_index-m_read_index;
//remain_size=m_max_size-used_size;
//cur_size=m_max_size-m_write_index;
//printf("已經(jīng)使用%d,剩余總長度%d,剩余當前長度%d\n",used_size,remain_size,cur_size);
流程圖中還出現(xiàn)隨機一段數(shù)據(jù),這是用來調(diào)試的。隨機初始化一段長度為0~40,字符a~z的數(shù)據(jù),并寫緩存區(qū)
staticintget_random_len(){
returnrand()%40;
staticintget_random_ala(){
returnrand()%26;
size_tBuffer::init_random_write(char**src)
intsize=get_random_len();
charala=get_random_ala();
*src=newchar[size];
cout"準備寫入的長度為"size"值全是"(unsignedchar)('a'+ala)endl;
for(inti=0;isize;i++){
(*src)[i]='a'+ala;
returnsize;
②讀取緩沖區(qū)read_from_buffer()
read_from_buffer(char*dst,intread_size)傳入需要拷貝到目的地址和需要讀取的字節(jié)數(shù),需要注意的是需要讀取的字節(jié)數(shù)為-1表示全部讀取,函數(shù)返回實際讀取的字節(jié)數(shù)。實現(xiàn)如流程圖所示:
代碼如下
size_tBuffer::read_from_buffer(char*dst,intread_size)
size_tread_max=m_write_index-m_read_index;//read_max存儲的字節(jié)數(shù)
if(read_size==0||read_max==0)//讀取0字節(jié)和空緩存區(qū)時直接返回
return0;
if(read_size==-1){//全讀走
memcpy(dst,m_s[m_read_index],read_max);
m_read_index+=read_max;
cout"讀取了"read_max"個字節(jié)"endl;
elseif(read_size0){//讀取指定字節(jié)
if((size_t)read_sizeread_max)
read_size=read_max;
memcpy(dst,m_s[m_read_index],read_size);
m_read_index+=read_size;
cout"讀取了"read_size"個字節(jié)"endl;
returnread_size;//返回讀取的字節(jié)數(shù)
③丟棄數(shù)據(jù)pop_bytes
size_tpop_bytes(size_tsize)傳入需要丟棄的字節(jié)數(shù),需要注意的是需要丟棄的字節(jié)數(shù)為-1表示全部丟棄;-2表示隨機丟棄0~40字節(jié),函數(shù)返回實際丟棄的字節(jié)數(shù)。實現(xiàn)如流程圖所示:
size_tBuffer::pop_bytes(size_tsize)
size_tread_max=m_write_index-m_read_index;//存儲數(shù)據(jù)長度
//testrandom
if(size==-2)
size=get_random_len();
if(size==0||read_max==0)//緩沖區(qū)為空或丟棄0字節(jié)返回
return0;
if(size==-1){//全丟
m_read_index+=read_max;
cout"丟棄了"read_max"個字節(jié)"endl;
returnread_max;
if(size0){//丟棄指定字節(jié)
if(sizeread_max)
size=read_max;
m_read_index+=size;
cout"丟棄了"size"個字節(jié)"endl;
returnsize;
④其他接口
peek_read()和peek_write()返回讀寫指針的位置
size_tpeek_read();//指向準備讀的位置(調(diào)試用)
size_tpeek_write();//指向準備寫的位置(調(diào)試用)
size_tBuffer::peek_write()
returnm_write_index;
size_tBuffer::peek_read()
returnm_read_index;
4.完整代碼與測試
①完整代碼
Buffer.h
#pragmaonce
classBuffer{
public:
Buffer();//構(gòu)造
~Buffer();//析構(gòu)
intinit();//分配緩沖區(qū)
voidwrite_to_buffer(char*src);//寫數(shù)據(jù)
size_tpop_bytes(size_tbytes);//丟棄數(shù)據(jù)
size_tread_from_buffer(char*dst,intbytes);//讀數(shù)據(jù)
size_treadable_bytes();//得到存儲數(shù)據(jù)的字節(jié)數(shù)
size_tpeek_read();//指向準備讀的位置(調(diào)試用)
size_tpeek_write();//指向準備寫的位置(調(diào)試用)
private:
voidadjust_buffer();//調(diào)整數(shù)據(jù)位置至緩沖區(qū)頭
voidexpand_buffer(size_tneed_size);//擴展緩沖區(qū)長度
size_tinit_random_write(char**src);//隨機初始化一段數(shù)據(jù)(調(diào)試用)
private:
char*m_s;//緩沖區(qū)指針
size_tm_read_index;//讀指針位置
size_tm_write_index;//寫指針位置
size_tm_max_size;//緩沖區(qū)長度
size_tm_expand_par;//擴展因子
Buffer.cpp:
#include"Buffer.h"
#includeiostream
#includetime.h
usingnamespacestd;
inttotal_write=0;//記錄總寫入
inttotal_read=0;//記錄總讀取
staticintget_random_len(){
returnrand()%40;
staticintget_random_ala(){
returnrand()%26;
Buffer::Buffer()
:m_read_index(0),m_write_index(0),m_max_size(10),m_expand_par(2),m_s(nullptr)
Buffer::~Buffer()
delete[]m_s;
intBuffer::init()
m_s=newchar[m_max_size]();
if(m_s==nullptr){
cout"分配m_s失敗\n";
return-1;
return0;
size_tBuffer::read_from_buffer(char*dst,intread_size)
size_tread_max=m_write_index-m_read_index;//read_max存儲的字節(jié)數(shù)
if(read_size==0||read_max==0)//讀取0字節(jié)和空緩存區(qū)時直接返回
return0;
if(read_size==-1){//全讀走
memcpy(dst,m_s[m_read_index],read_max);
m_read_index+=read_max;
printf("讀取完成:\t讀取%d個字節(jié)\n",read_max);
total_read+=read_max;
elseif(read_size0){//讀取指定字節(jié)
if((size_t)read_sizeread_max)
read_size=read_max;
memcpy(dst,m_s[m_read_index],read_size);
m_read_index+=read_size;
printf("讀取完成:\t讀取%d個字節(jié)\n",read_size);
total_read+=read_size;
returnread_size;//返回讀取的字節(jié)數(shù)
size_tBuffer::readable_bytes()
returnm_write_index-m_read_index;
size_tBuffer::peek_write()
returnm_write_index;
size_tBuffer::peek_read()
returnm_read_index;
voidBuffer::write_to_buffer(char*src)
size_tused_size=m_write_index-m_read_index;//used_size表示已經(jīng)存儲的字節(jié)數(shù)
size_tremain_size=m_max_size-used_size;//remain_size表示剩余空間
size_tcur_size=m_max_size-m_write_index;//cur_size表示當前能夠存儲的空間
size_tsize=init_random_write(src);
//printf("已經(jīng)使用%d,剩余總長度%d,剩余當前長度%d\n",used_size,remain_size,cur_size);
if(sizeremain_size){//剩余空間不夠
adjust_buffer();
expand_buffer(size);
elseif(sizecur_size){//剩余空間夠,當前存不下
adjust_buffer();
memcpy(m_s[m_write_index],src,size);//存儲數(shù)據(jù)
m_write_index+=size;
delete[]src;
//更新并打印log
used_size=m_write_index-m_read_index;
remain_size=m_max_size-used_size;
cur_size=m_max_size-m_write_index;
printf("寫入完成:\t總存儲%d,剩余空間%d,剩余當前空間%d\n",used_size,remain_size,cur_size);
size_tBuffer::pop_bytes(size_tsize)
size_tread_max=m_write_index-m_read_index;//存儲數(shù)據(jù)長度
//testrandom
if(size==-2)
size=get_random_len();
if(size==0||read_max==0)//緩沖區(qū)為空或丟棄0字節(jié)返回
return0;
if(size==-1){//全丟
m_read_index+=read_max;
cout"丟棄了"read_max"個字節(jié)"endl;
total_read+=read_max;
returnread_max;
if(size0){//丟棄指定字節(jié)
if(sizeread_max)
size=read_max;
m_read_index+=size;
cout"丟棄了"size"個字節(jié)"endl;
total_read+=size;
returnsize;
size_tBuffer::init_random_write(char**src)
intsize=get_random_len();
total_write+=size;
*src=newchar[size];
charala=get_random_ala();
cout"隨機寫入:\t長度為"size"值全是"(unsignedchar)('a'+ala)endl;
for(inti=0;isize;i++){
(*src)[i]='a'+ala;
returnsize;
voidBuffer::adjust_buffer()
if(m_read_index==0)//數(shù)據(jù)已經(jīng)在頭部,直接返回
return;
intused_size=m_write_index-m_read_index;
if(used_size==0){//緩沖區(qū)為空,重置讀寫指針
m_write_index=0;
m_read_index=0;
else{
cout"調(diào)整前read_indexwrite_index"m_read_index""m_write_indexendl;
memcpy(m_s,m_s[m_read_index],used_size);//將數(shù)據(jù)拷貝至頭部
m_write_index-=m_read_index;//寫指針也前移
cout"調(diào)整了"used_size"個字節(jié)"endl;
m_read_index=0;//讀指針置0
cout"調(diào)整后read_indexwrite_index"m_read_index""m_write_indexendl;
voidBuffer::expand_buffer(size_tneed_size)//need_size需要寫入的字節(jié)數(shù)
size_tused_size=m_write_index-m_read_index;//used_size表示已經(jīng)存儲的字節(jié)數(shù)
size_tremain_size=m_max_size-used_size;//remain_size表示剩余空間
size_texpand_size=m_max_size;
while(remain_sizeneed_size){//剩余空間不夠時擴展,用while表示直到擴展至夠用
expand_size*=m_expand_par;
remain_size=expand_size-used_size;
cout"擴展長度中...總剩余總長度"remain_size""expand_sizeendl;
char*s1=newchar[expand_size]();//申請新的空間
memcpy(s1,m_s,m_max_size);
free(m_s);
m_s=s1;//將新空間掛載到緩沖區(qū)
m_max_size=expand_size;//更新緩沖區(qū)總長度
cout"擴展結(jié)束,總長度為"m_max_sizeendl;
②測試
intmain(){
srand((unsigned)time(NULL));//調(diào)試需要初始化隨機種子
Buffer*pbuffer=newBuffer();//創(chuàng)建Buffer對象
if(pbuffer-init()!=0)//init函數(shù)分配緩沖區(qū)
return0;
char*s=nullptr;//s是指向隨機數(shù)據(jù)的指針
char*read=newchar[1000];//讀取時將數(shù)據(jù)存儲到的指針read
size_tread_size=0;//本次讀取到的字節(jié)數(shù)
pbuffer-write_to_buffer(s);
read_size=pbuffer-read_from_buffer(read,-1);
pbuffer-write_to_buffer(s);
pbuffer-pop_bytes(-2);
read_size=read_size=pbuffer-read_from_buffer(read,0);
pbuffer-write_to_buffer(s);
cout"總寫入\t"total_writeendl;;
cout"總讀取\t"total_readendl;
cout"目前寫入"total_write-total_readendl;
cout"可讀取\t"pbuffer-readable_bytes()endl;
printf("write%dread%d\n",pbuffer-peek_write(),pbuffer-peek_read());
if(total_write-total_read!=pbuffer-readable_bytes()){//根據(jù)總寫入-總讀取和一共存儲的字節(jié)數(shù)判斷是否存儲正確
cout"error!!!"endl;
else
cout"testisok\n\n\n";
deletes;
delete[]read;
deletepbuffer;
return0;
隨機1000000次測試
intmain(){
srand((unsigned)time(NULL));//調(diào)試需要初始化隨機種子
Buffer*pbuffer=newBuffer();//創(chuàng)建Buffer對象
if(pbuffer-init()!=0)//init函數(shù)分配緩沖區(qū)
return0;
char*s=nullptr;//s是指向隨機數(shù)據(jù)的指針
char*read=newchar[1000];//讀取時將數(shù)據(jù)存儲到的指針read
size_tread_size=0;//本次讀取到的字節(jié)數(shù)
unsignedlonglongtime=0;//調(diào)試的循環(huán)次數(shù)
while(1){
pbuffer-write_to_buffer(s);
read_size=pbuffer-read_from_buffer(read,-1);
pbuffer-write_to_buffer(s);
pbuffer-write_to_buffer(s);
pbuffer-pop_bytes(-2);
read_size=read_size=pbuffer-read_from_buffer(read,0);
pbuffer-write_to_buffer(s);
pbuffer-pop_bytes(-2);
pbuffer-write_to_buffer(s);
read_size=pbuffer-read_from_buffer(read,-1);
pbuf
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 統(tǒng)編版2025-2026學年語文四年級第一學期期末質(zhì)量檢測練習卷(含答案)
- 湖南省岳陽市汨羅市2025-2026學年八年級上學期1月期末生物試題(無答案)
- 河南省駐馬店市泌陽縣2025-2026學年八年級上學期1月期末考試歷史試卷答案
- 2025-2026學年一年級(上)期末游戲化測試語文試卷(附參考答案)
- 五年級題目及答案
- 文件筐測試題及答案
- 2026年小學語文模擬沖刺押題卷
- 誠實做事的演講稿
- 冀教版三年級上冊數(shù)學第二單元-兩、三位數(shù)乘一位數(shù)-測試卷及答案(奪冠系列)
- 高中高二下學期地理期末考試試題答案解析
- 蘇教版高中化學必修二知識點
- 2024年國家公務員考試國考中國人民銀行結(jié)構(gòu)化面試真題試題試卷及答案解析
- 2025年中考語文一輪復習:民俗類散文閱讀 講義(含練習題及答案)
- 高中數(shù)學選擇性必修一課件第一章 空間向量與立體幾何章末復習(人教A版)
- 標準商品房買賣合同文本大全
- LY/T 3408-2024林下經(jīng)濟術(shù)語
- 2025年湖南邵陽市新邵縣經(jīng)濟開發(fā)區(qū)建設有限公司招聘筆試參考題庫附帶答案詳解
- 2023-2024學年八年級(上)期末數(shù)學試卷
- DB33T 1238-2021 智慧燈桿技術(shù)標準
- ICH《M10:生物分析方法驗證及樣品分析》
- 福建省泉州市晉江市2023-2024學年八年級上學期期末考試數(shù)學試卷(含解析)
評論
0/150
提交評論