1. 程式人生 > >常用物聯網應用層協議(1)——先說HTTP協議

常用物聯網應用層協議(1)——先說HTTP協議

# 概念 ## 簡介 HTTP是一個屬於應用層的面向物件的協議,目前使用最為廣泛的是HTTP1.1協議。當然,許多網站已經開始支援HTTP2.0,HTTP2複雜度高於HTTP1.1,我們先從HTTP1.1說起。 HTTP於1990 年提出,經過幾年的使用與發展,得到不斷地完善和擴充套件。主要有以下特點: * 支援客戶/伺服器模式 * ASCII碼傳輸,人能直接讀懂 * 引數靈活 * *無連線/無狀態(僅針對HTTP2以前的版本) ## 兩個重要的網站 1.https://www.ietf.org/rfc/ 主要儲存RFC標準文件 2.https://zh.wikipedia.org/zh-cn/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE 這個地址是關於HTTP的詳細介紹 ## 關於RFC RFC:Request For Comments(RFC),是一系列以編號排定的檔案。檔案收集了有關網際網路相關資訊,以及UNIX和網際網路社群的軟體檔案。RFC檔案是由Internet Society(ISOC)贊助發行。基本的網際網路通訊協議都有在RFC檔案內詳細說明。RFC檔案還額外加入許多在標準內的論題,例如對於網際網路新開發的協議及發展中所有的記錄。因此幾乎所有的網際網路標準都有收錄在RFC檔案之中。(來自百度百科) RFC2026將標準定義位4個階段:因特網草案、建議標準、草案標準、因特網標準。更多的過程可以看看這些檔案: * RFC 2223 "Instructions to RFC Authors"。 * RFC 2026 "The Internet Standards Process -- Revision 3"。 ## 瀏覽器輸入某個網站地址並按下回車後發生了什麼 假設我們在瀏覽器鍾輸入www.abc.com,這個網站的IP地址是11.22.33.44,當回車按下後計算機將做如下工作: 1.首先檢查本地的各種快取,比如DNS快取、網站內容快取等,如果有並且規則表明不需在伺服器查詢則直接展示內容出來 2.檢查本地的hosts配置,如果輸入的網站域名在本機有配置則載入本機配置的IP地址,比如我們直接配置了一條hosts如下: ```text 11.22.33.44 www.abc.com ``` 那麼計算機將會直接向11.22.33.44這個地址傳送資料,而不會做DNS查詢。 3.如果本機什麼都沒有則進行DNS查詢,DNS和本機的hosts類似,即傳入www.abc.com,然後DNS伺服器返回給機器11.22.33.44,這個DNS伺服器即我們在TCP/IP裡面填寫的伺服器地址,它使用的是UDP傳輸。 4.使用IP建立連線,需要記住的是在網際網路世界裡面只有IP地址才是唯一地址,而網站域名只是一種別名,在連線伺服器的過程中也是使用IP地址進行連線。 5.傳送客戶端請求的資料。 6.接收服務端響應的資料。 當然,實際情形下遠不止以上幾步這麼簡單,以上的每一步也可以拆分位許多小步,甚至形成一篇新的文章,但是基本流程就是這樣。 ## 怎麼觀察HTTP協議內容 如上文所說,HTTP協議是基於應用層的協議,那麼計算機網路抓包過後的應用層資料即包含HTTP協議的內容,在windows裡面我們可以採用大名鼎鼎的wireshark進行資料報文的抓取,然後篩選HTTP協議進行觀察,也可以使用smartsniff這樣小而精的軟體專門抓取應用層內容,在Linux裡面直接使用tcpdump進行抓取即可,然後將抓取的結果使用相關的軟體開啟觀察,也可以匯入到wireshark進行觀察。一個實際抓取的較為典型的HTTP內容如下: ``` text 客戶端請求: POST /devices HTTP/1.1 Host: www.abc.com Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 a=b&c=d 伺服器響應: HTTP/1.1 200 OK Date: Tue, 27 Oct 2020 02:13:39 GMT Content-Type: application/json Content-Length: 5 Connection: keep-alive Server: nginx Pragma: no-cache Hello ``` # 協議詳解 ## HTTP之URL HTTP URL格式如下: ```text http://host[":"port][abs_path] ``` host 表示合法的 Internet 主機域名或者 IP 地址 port 指定一個埠號,為空則使用預設埠 80 abs_path 指定請求資源的 URI 舉幾個例子: ```text http://www.abc.com http://www.abc.com:8080 http://www.abc.com/devices http://www.abc.com:8080/devices/data http://11.22.33.44/devices/data http://11.22.33.44:8080/devices/data ``` 以上均符合HTTP URL的定義,我們可以簡單地將其理解位我們在瀏覽器裡面輸入的網站域名 ## HTTP之請求 ### 請求組成部分 http請求由三部分組成,分別是:請求行、訊息報頭、請求正文 ### 關於請求行 請求行以一個方法符號開頭,以空格分開,後面跟著請求的URI和協議的版本,即 ```text Method Request-URI HTTP-Version CRLF ``` 針對Method有以下定義,並且必須使用以下定義的內容,如果填入其他的資料那麼就不是標準的HTTP協議(雖然一部分伺服器能自動糾錯) * GET 請求獲取 Request-URI 所標識的資源 * POST 在 Request-URI 所標識的資源後附加新的資料 * HEAD 請求獲取由 Request-URI 所標識的資源的響應訊息報頭 * PUT 請求伺服器儲存一個資源,並用 Request-URI 作為其標識 * DELETE 請求伺服器刪除 Request-URI 所標識的資源 * TRACE 請求伺服器回送收到的請求資訊,主要用於測試或診斷 * CONNECT 保留將來使用 * OPTIONS 請求查詢伺服器的效能,或者查詢與資源相關的選項和需求 常用的Method只有GET以及POST,如果有涉及到協議轉換,比如HTTP1轉換到HTTP2、HTTP轉換到HTTPS或者轉換為websocket,可能回使用OPTIONS方法先詢問。至於其他的方法通常不怎麼用,值得注意的是標準的restful介面業務會在GET和POST基礎上還有PUT和DELETE方法。 針對Request-URI則是我們在瀏覽器輸入的域名和端後後面的內容,比如/devices,如果是根目錄,比如www.abc.com,實際上Request-URI是“/”,即預設都是“/”開始,這樣的目錄結構和Linux的目錄結構類似,而實際上也是來源於它。 HTTP-Version我們常用的是HTTP/1.1,當然,現在也有部分網站使用HTTP/2 第一節的客戶端請求裡面第一行則是請求行的內容,具體如下: ```text POST /devices HTTP/1.1 ``` ### 關於訊息報頭 在第一節關於HTTP抓包的請求例項中,除了a=b&c=d這一個內容外其餘的全是訊息報頭,即 ```text Host: www.abc.com Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 ``` 這裡面也是HTTP核心東西之一,它以key: value的形式成對出現,除了上述內容外,我們常說的cookie、session等通常情況下也是放在訊息報頭中進行傳輸 我們也常說HTTP Header,直接將訊息報頭理解為HEADER裡面的所有東西也是沒什麼問題的。 ### 關於請求正文 上述例子中,“a=b&c=d”即是請求正文,請求正文通常情況下有按照form形式、按照json形式進行傳輸,但是也可以自由發揮填充任意東西,只要服務端能去解析即可。 關於form形式除了最簡單的a=b&c=d外還有mutiform等形式,也是在請求頭中進行定義,然後請求正文使用相應的格式進行資料填充。 ### 具體請求例子 具體的例子裡面我們將以最小的報文頭進行展示而展示無關的資訊 * 開啟www.abc.com網站首頁 ``` text GET / HTTP/1.1 Host: www.abc.com ``` * 以GET形式傳入username為haha以及password為hehe到www.abc.com網站的登入介面(假設為/login) ``` text GET /login?username=haha&password=hehe HTTP/1.1 Host: www.abc.com ``` * 以POST標準FORM形式傳入username為haha以及password為hehe到www.abc.com網站的登入介面(假設為/login) ``` text POST /login HTTP/1.1 Host: www.abc.com username=haha&password=hehe ``` * 以POST標準json形式傳入username為haha以及password為hehe到www.abc.com網站的登入介面(假設為/login) ``` text POST /login HTTP/1.1 Host: www.abc.com {"username":"haha","password":"hehe"} ``` * 查詢www.abc.com網站的裝置列表,並帶上cookie為123456(假設為/devicelist) ``` text GET /devicelist HTTP/1.1 Host: www.abc.com Cookie: 123456 ``` * 查詢www.abc.com網站的裝置列表,並帶上cookie為123456,要求服務端保持連線(假設為/devicelist) ``` text GET /devicelist HTTP/1.1 Host: www.abc.com Cookie: 123456 Connection: keep-alive ``` # 總結和後續計劃 本文主要講解了HTTP一些基本概念以及請求相關的報文。 接下來第二篇將講解HTTP響應、HTTP2簡介以及當下主流的HTTPS簡單互動過程,最後將模擬請求一次網站並進行抓包