溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

boost.asio框架系列之buffer函數(shù)怎么使用

發(fā)布時(shí)間:2022-06-20 09:28:18 來源:億速云 閱讀:250 作者:iii 欄目:開發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“boost.asio框架系列之buffer函數(shù)怎么使用”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“boost.asio框架系列之buffer函數(shù)怎么使用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識(shí)吧。

創(chuàng)建buffer

在io操作中,對(duì)數(shù)據(jù)的讀寫大都是在一個(gè)緩沖區(qū)上進(jìn)行的,在asio框架中,可以通過asio::buffer函數(shù)創(chuàng)建一個(gè)緩沖區(qū)來提供數(shù)據(jù)的讀寫。buffer函數(shù)本身并不申請(qǐng)內(nèi)存,只是提供了一個(gè)對(duì)現(xiàn)有內(nèi)存的封裝。

char d1[128];
size_t bytes_transferred = sock.receive(asio::buffer(d1));

直接用字符串做buffer也是常見的形式:

string str = " hello world " ;
size_t bytes_transferred = sock.send(asio::buffer(str));

除了這些基礎(chǔ)類型外,也可以使用stl中的容器,非常方便。

asio::buffer(std::vector<char>(128));
asio::buffer(std::array<char,128>());

將buffer還原為數(shù)據(jù)對(duì)象

前面的操作是通過把數(shù)據(jù)對(duì)象封裝成buffer,在使用過程中往往也需要把buffer還原為數(shù)據(jù)對(duì)象。

char* p1 = asio::buffer_cast<char*>(buffer);

獲取buffer大小

可以通過buffer_size函數(shù)獲取buffer大小。

size_t s1 = asio::buffer_size(buf);

讀寫buffer

讀寫buffer一般都是和io對(duì)象相關(guān)聯(lián)的,io對(duì)象成員函數(shù)中就提供了讀寫操作。以tcp::socket對(duì)象為例,它提供了read_some和write_some來實(shí)現(xiàn)讀寫操作:

std::array<char, 128> buf;
sock.read_some(asio::buffer(buf));

另外,asio名字空間下也提供了通用的read、write函數(shù),通過它們可以實(shí)現(xiàn)更加高級(jí)的讀寫功能

size_t bytes_transfered = asio::read(sock, asio::buffer(buf), asio::transfer_all(), err);

這里我就使用了transfer_all標(biāo)記強(qiáng)制讀滿buffer才返回,另外還有兩個(gè)比較常用的標(biāo)記transfer_at_least()和transfer_exactly(),非常方便。

streambuf

asio::streambuf則是提供了一個(gè)流類型的buffer,它自身是能申請(qǐng)內(nèi)存的。它的好處是可以通過stl的stream相關(guān)函數(shù)實(shí)現(xiàn)緩沖區(qū)操作,處理起來更加方便。

    //通過streambuf發(fā)送數(shù)據(jù)
    asio::streambuf b;
    std::ostream os(&b);
    os << "Hello, World!\n";

    size_t n = sock.send(b.data());    // try sending some data in input sequence
    b.consume(n); // sent data is removed from input sequence

 

    //通過streambuf讀數(shù)據(jù)
    asio::streambuf b;
    asio::streambuf::mutable_buffers_type bufs = b.prepare(512);    // reserve 512 bytes in output sequence
    size_t n = sock.receive(bufs);
    b.commit(n);    // received data is "committed" from output sequence to input sequence

    std::istream is(&b);
    std::string s;
    is >> s;

另外,asio名字空間下還提供了一個(gè)的read_until函數(shù),可以實(shí)現(xiàn)讀到滿足指定條件的字符串為止,對(duì)于解析協(xié)議來說非常有用。

size_t n = asio::read_until(sock, stream, '\n');
asio::streambuf::const_buffers_type bufs = sb.data();
std::string line(asio::buffers_begin(bufs), asio::buffers_begin(bufs) + n);

這個(gè)指定條件除了是字符串外,還可以是正則表達(dá)式,非常給力。這也是asio庫為什么要依賴于boost.regex的原因。(雖然regex已經(jīng)標(biāo)準(zhǔn)化了,但仍得使用boost.regex庫。等什么時(shí)候asio也標(biāo)準(zhǔn)化后估計(jì)就可以直接使用std.regex庫了)

自定義內(nèi)存分配

異步IO操作時(shí)往往會(huì)申請(qǐng)動(dòng)態(tài)內(nèi)存,使用完后就釋放掉;在IO密集型的場景中,頻繁的申請(qǐng)釋放內(nèi)存對(duì)性能會(huì)有較大影響。為了避免這個(gè)問題,asio提供了一個(gè)內(nèi)存池式的模型 asio_handler_allocate 和 asio_handler_deallocate 來復(fù)用內(nèi)存。

讀到這里,這篇“boost.asio框架系列之buffer函數(shù)怎么使用”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI