c++實現(xiàn)一個簡易的網(wǎng)絡緩沖區(qū)的實踐_第1頁
c++實現(xiàn)一個簡易的網(wǎng)絡緩沖區(qū)的實踐_第2頁
c++實現(xiàn)一個簡易的網(wǎng)絡緩沖區(qū)的實踐_第3頁
c++實現(xiàn)一個簡易的網(wǎng)絡緩沖區(qū)的實踐_第4頁
c++實現(xiàn)一個簡易的網(wǎng)絡緩沖區(qū)的實踐_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論