您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關怎么寫一個Webserver的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
我寫Webserver的原因,還得從如何將http協議傳送的消息解析說起.當時,我只是想了解一下http的消息解析過程,好能夠提高基于http協議的消息處理效率,所以就在網上搜了一下,發現很多人都在用nodejs的http-parser,也許是智商上限封頂^_^!,我居然沒太看懂大神的代碼邏輯.后來也考察過h3o這個項目的parser,無奈還是沒有能領悟大神的精神^_^!.
怎么辦...,掙扎了半天,最終決定硬著頭皮自己寫一個http消息的parser吧.就醬,就有了后來我寫Maestro Webserver的故事.
既然談到了http message的解析,那今天這第一篇隨筆就談這個東西吧.http協議的內容說起來歷史太久遠了,我不是歷史老師,網上很多講解都很棒,我就不多說了.此外,RFC2616, RFC7231等文檔也明確的講解了協議的含義.不過還是應該吐槽一下RFC文檔的晦澀難懂哈...
還是讓我引用一段相對清晰的關于http message的RFC講解吧
HTTP messages consist of requests from client to server and responses from server to client. HTTP-message = Request | Response ; HTTP/1.1 messages Request (section 5) and Response (section 6) messages use the generic message format of RFC 822 [9] for transferring entities (the payload of the message). Both types of message consist of a start-line, zero or more header fields (also known as "headers"), an empty line (i.e., a line with nothing preceding the CRLF) indicating the end of the header fields, and possibly a message-body. generic-message = start-line *(message-header CRLF) CRLF [ message-body ] start-line = Request-Line | Status-Line
從這段文字中,我們可以知道不論是request還是response,http message分三段,即start-line,message headers和message body.
那么,在設計我的messge結構體時(對了,我是用C語言開發的),我會包含這三段內容.我并沒有把parser寫成獨立的單一函數,而是將他們分解成了一組能重復被調用的更小的函數.而從封裝的角度來說,我也沒有遵守盡量封裝數據結構體的原則.我的目的很簡單,那就是,簡單易懂,容易調用(這會不會被老師調打一頓:-).
還是看看定義的數據結構體吧.
typedef struct { int method; /* GET/POST... */ char *path; int ver_major; int ver_minor; int code; /* status code */ char *status; /* status text */ sllist_t *headers; int len_startline; int len_headers; unsigned char *body; unsigned char *body_zipped; unsigned char *body_s; /* point to the range start of the body */ size_t len_body; } httpmsg_t;
先不用看和body相關的部分,因為我會在后續如何寫Webserver中介紹相關的內容(涉及到body的壓縮,斷點續傳等等).
下面是相關的函數,鄭州醫大男科醫院http://www.xasgnanke.com/
int msg_parse(sllist_t *headers, unsigned char **startline, unsigned char **body, size_t *len_body, const unsigned char *buf);
這個是對底層message進行解析的函數,再此之上,我用兩個函數封裝了它,分別用于解析http request和http response.
httpmsg_t *http_parse_req(const unsigned char *buf); httpmsg_t *http_parse_rep(const unsigned char *buf);
我寫這些底層函數的原則是,盡量利用上一步的結果,不做重復的計算,比如,同一字符串的長度不要多次通過strlen計算,希望這樣應該能提高的性能吧.
在上面的httpmsg_t結構體中,我用了單鏈表來管理http headers,因為headers的數量不是很多,單鏈表輪詢反而速度更快.
感謝各位的閱讀!關于“怎么寫一個Webserver”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。