在beast文件中,專門解釋了是如何構思http request和response類的。request和response的定義如下:
templateclass message:public header,boost::empty_value
以上的定義與文件中稍有不同,來自於源**,文件中說message是乙個容器,包含header與body,實際上message是繼承於header與body,文件中的描述大致是為了更好理解,功能應該是一樣的。當isrequest是true時就是request,是false時就是response。
header的定義也是如此,文件中header有isrequest引數模板,但原始碼中被偏特化為兩個類了,如下:
//request header
templateclass header: public fields
//response header
templateclass header: public fields
一般情況下,request和response基本上是沒有關係的,是否將二者定義為同乙個模板類,可能各人有各人的想法。
各類之間的關係如下圖所示。出現模板的概念後,類之間的關係不好表達了,原來靜態的關係變成了動態(模板例項化後其實是乙個新類),因此下圖僅是乙個示意。
fields(basic_fields)是各種key-value的集合,該類內部有乙個boost::intrusive::multiset和boost::intrusive::list,field被定義為enum class,集合儲存的元素其實是(element+content),它是一段記憶體塊,主體是element+name+value,其中element中包含了field,**示意如下:
auto const p = alloc_traits::allocate(a,
(sizeof(element) + (name長)+ (value長) + 2 + sizeof(align_type) - 1) /
sizeof(align_type));
*(::new(p) element(name, sname, value));
fields類提供了element的管理。
file_body等提供了對各種body型別的封裝,基本上它包括三個內容
beast這種構造request/response的方法,要求在最開始的時候就知道它的型別,然後採用已定義好的「模板」來裝載它,如果這種流式資訊的結構在開始時不能得到或不易得到(例如層級結構,還沒收到完整的資訊),怎麼會有確定的「模板」?
beast作者將型別作為模板作為類構造的輸入,可能與作者過於強調「模板」思路有關(beast自帶例子中,很多是模板函式),並沒有乙個通用的request和response基類,有時候會顯得不自然,例如,當請求乙個檔案時,就會產生3種response:正常情況下的response;不存在檔案下的response(此時不定製錯誤資訊);異常情況下的response(此時定製錯誤資訊)。我們通常的思路似乎是構造乙個通用response(或基類),然後裝載不同類(file/system error/string)的serialization後的結果。
以下是beast文件中提供的乙個方案的例子,思路是首先構造empty_body的request,讀取header,然後根據content_type的內容再將request修改(move)為string_body或dynamic_body型別。
request_parserreq0;
read_header(stream, buffer, req0);
switch(req0.get().method())
;read(stream, buffer, req);
handler(req.release());
break;
}do_dynamic_body:
default:
;read(stream, buffer, req);
handler(req.release());
break;}}
chunked body不同於乙個完整的body,它由若干如下結構的塊構成:
xx:extension\r\n
content\r\n
其中xx(十六進製制)表示下面content的長度,extension可選,是形如k1[=v1];k2[=v2]這樣的key=value對(value可選),content是本塊的內容。
beast提供了以下類:
2個函式make_chunk,make_chunk_last用於生成chunk_body和chunk_last。
使用的流程大致是(以reponse為例):
responseres; //構造response
res.set(…); //設定field
res.chunked(true); //設定chunked模式
response_serializersr; //寫header
write_header(sock, sr);
chunk_extensions ext; //構造extension
ext.insert(…);
// 寫chunk塊, chunk塊的內容已被寫入const_buffer(可參見buffer的用法)
net::write(sock, make_chunk(const_buffer,ext));
…net::write(sock, make_chunk_last()); //寫入最後塊
有關chunk的結構設計得比較麻煩,但通過make_chunk,make_chunk_last,使用起來並不麻煩。 Boost Beast要點解析(四)
由於http websocket僅涉及tcp,因此在beast範圍內,也僅涉及tcp協議,beast的網路操作基於asio,但beast的乙個目標似乎是做乙個完整的系統 猜測 因此beast將涉及到的網路資料操作都 重寫 的一遍 一些是簡單包裝,一些是擴充套件 例如asio空間被重新命名為net,對...
HTML CSS章節要點解析
1.html中定義 的寬度用80px和80 的區別是px標識畫素,標識整個頁面的寬度百分比 2.css樣式定義優先順序順序 內聯樣式最高優先權,然後是內部樣式,然後才是外部樣式3.div 和 span 元素最大的特點是預設都沒有對元素內的物件進行任何格式化渲染。主要用於應用樣式表 共同點 兩者最明顯...
感測器的設計要點解析
好的感測器 的設計是經驗加技術的結晶。一般理解感測器是將一種物理量經過 電路轉換成一種能以另外一種直觀的可表達的物理量的描述。而下文我們將對感測器的概念 原理特性進行逐一介紹,進而解析感測器的設計的要點。1 感測器的概念 感測器是一種檢測裝置,能感受到被測量的資訊,並能將感受到的資訊,按一定規律變換...