原始碼下載地址
案例開發環境:VS2010
本案例未使用openssl庫,內部提供了sslite.dll庫進行TLS會話,該庫提供了ISSLSession介面用于建立SSL會話,
HTTP協議很簡單,寫個簡單的socket程式通過GET命令就能把網頁給down下來,但接收大的網路資源就復雜多了,何時決議、如何決議完整的HTTP回應頭,就是個頭疼問題,因為你不能指望一次recv就能接收完所有回應資料,也不能指望服務器先發送HTTP回應頭,然后再發送回應資料,只有把HTTP回應頭徹底決議了,我們才能知道后續接收的Body資料有多大,何時才能接收完畢,
比如通過回應頭的"Content-Length"欄位,才能知道后續Body的大小,這個大小可能超過了你之前開辟的接收資料快取區大小,當然你可以在得知Body大小后,重新開辟一個與"Content-Length"一樣大小的快取區,但這樣做顯然是不明智的,比如你get的是一部4K高清藍光小電影,藍光電影不一定能get到,藍屏電腦倒有可能get到,,,,,,
遇到服務器明確給出"Content-Length"欄位,是一件值得額手稱慶的大喜事,但不是每個IT民工都這么幸運,如果遇到的是不靠譜的服務器,發送的是"Transfer-Encoding: chunked",那你就必須鍛煉自己真正的決議和組織能力了,這些分塊傳輸的資料,顯然不會以你接收的節奏到達你的緩沖區,比如先接收到一個block塊大小,然后是一個完整的塊資料,很有可能你會接收到多個塊或者不完整的塊,這就需要你站在宏觀的角度把他們拼接起來,
如果你遇到的是甩的一米的服務器,它不僅給你的是chunked,而且還增加了"Content-Encoding: gzip",那么你就需要拼接后進行解壓,當然你也可能遇到的是"deflate"壓縮,
附:我寫過web服務器,所以也知道服務器的心理,,,,,,
HttpServer:一款Windows平臺下基于IOCP模型的高并發輕量級web服務器
題外話:我一直困惑的是HTTP協議為何不是對分塊資料單獨gzip壓縮然后傳輸,而只能是整體gzip壓縮后再分塊傳輸,這個對大資源傳輸很關鍵,比如上面的4K高清藍光小電影,顯然不能通過gzip+chunked方式傳輸,土豪服務器例外,
當然你也可以用開源的llhttp來決議收到的http資料,從而避免上述可能會遇到的各種坑,最新版本的nodejs中就使用llhttp代替之前的的http-parser,據說決議效率有大幅提升,為此我下載了nodejs原始碼,并編譯了一把,這是一個快樂的程序,因為你可以看到v8引擎,openssl,zlib等各種開源庫,,,,,不過llhttp只負責決議,不負責快取,因此你還是需要在決議的程序中,進行資料快取,
關于V8引擎的使用參見文章
V8引擎靜態庫及其呼叫方法
以下是sslite庫提供的介面,SSLConnect是建立連接,SSLHandShake是SSL握手,握手成功后即可呼叫SSLSend和SSLRecv進行資料接收和發送,非常簡單,如果接收資料很多,SSLRecv會通過回呼函式將資料拋給呼叫層,
以下是原始碼,注釋很多,就不一一解釋了,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/285519.html
標籤:C++
上一篇:C++記憶體管理機制
