一文详解 TCP/IP 协议
荷西:你是不是一定要嫁個有錢人。
三毛:如果我不愛他,他是百萬富翁我也不嫁,如果我愛他,他是千萬富翁我也嫁。
荷西:。。。說來說去你還是要嫁有錢人。
三毛:也有例外的時候。
荷西:如果跟我呢?
三毛:那只要吃得飽的錢也算了。
荷西思索了一下:你吃得多嗎?
三毛十分小心的回答:不多,不多,以后還可以少吃點。
---- 三毛《撒哈拉的故事》
文章內容主要摘抄自《STM32 物聯網實戰教程》,個人有些許改動。
一、TCP/IP 模型 概述
計算機網絡在物聯網應用中起到舉足輕重的作用,它是硬件設備連接網絡的基石。
目前提到計算機網絡協議指的就是著名的 TCP/IP 協議,只要是連接到網絡的設備其內部都是使用的 TCP/IP 協議。TCP/IP 協議是眾多協議的集合,根據 TCP/IP 的分層不同,對應的協議族也不同,下圖是列舉了 TCP/IP 包含的各個層的通信協議:
在平時的物聯網項目的開發時,并不會涉及到的所有協議,常用的就是傳輸層的 TCP 協議和 UDP 協議,需要了解的是應用層的 HTTP、DHCP、DNS、FTP 、SMTP 和 和 NTP 協議, 以及一些網絡基礎知識,如 IP 的概念和分類,域名的劃分和解析等 。
由于 TCP/IP 網絡協議非常復雜,本文只講解開發時用到的一些基礎知識和基本的通信協議,在學習了這些基本的通信協議之后再去深入學習計算機網絡將會非常容易。
TCP/IP 由于十分復雜,因此采用了分層設計的思想,共分為 4 層,從上往下依次是調用的關系,如下圖:
TCP/IP 協議位于應用層、傳輸層和網絡層。
網絡接口層只是實現 TCP/IP 協議的物理設備和驅動(網卡),其實就是物理層和數據鏈路層。
網絡層用于甄別數據傳輸介質中的某一數據包的是否屬于本機,如果是則解析數據包并去掉數據的 IP 首部,接著將數據發給傳輸層處理,
傳輸層在經解析去掉 TCP 首部,并將數據發送給對應的端口。也就是說數據的發送是從應用層開始封包,一層一層的套包裝,接收數據則是拆包裝的過程。如下圖所示:
整個發送過程,其實就是發送端不斷給數據加上幀頭,而接受端是不斷去掉幀頭,最終得到原始的數據的過程。
OSI 的標準是七層模型,而 TCP/IP 協議只分為四層,以下是對比圖:
如果想了解 OSI 模型,可以點擊下載 《科來 TCP/IP網絡協議圖 2020》。
二、TCP/IP 封包和共享傳輸介質
TCP/IP 采用共享傳輸介質的方式來進行多機的數據傳輸,比如同處于家庭無線局域網內的所有設備,或者使用同一根網線的多臺計算機,如果不采取任何機制直接使用這種方式進行多臺計算機的網絡通信就會導致一個很嚴重的問題:一臺計算機想要發送一個大文件,則會長時間占用硬件傳輸介質,迫使其他計算機處于等待狀態,使得網絡速度下降,傳輸實時性降低,為此 TCP/IP 針對共享傳輸介質采用了封包的概念,即:將用戶 的信息切割成多份并投放入傳輸介質中,但是這種封包進行傳輸不能保證各個數據包是按順序傳輸的,因此TCP/IP 為每個包都加入了順序編號,接收端會將這些數據包按照編號重新整理組合成原始數據。
在使用這種封包的傳輸機制之后,使得每臺計算機的等待時間大大降低,在計算機想要發送數據之前,它會先在傳輸線上試探一下是否有數據包正在發送,如果有數據發送它會自己擲骰子來生成一個隨機延時,等到延時結束接著試探,以此類推,所以我們會有這種經歷,當一條網線上的接入設備較多后,網絡會卡頓,其原因就是你的計算機檢測到此時網線上有數據傳輸,自己在那里不停的擲骰子,導致傳輸延時。
如下圖舉例,ABC 三個用戶正在使用通訊軟件傳輸消息,但這些消息在傳輸介質中卻是以不可預知的順序傳輸的。
三、IP 地址(定位到聯網設備)及端口號(定位到設備中的具體應用)
雙方計算機進行通信的前提是知道目標計算機的網絡位置,即我們所說的 IP地址 ,這是因為 IP 地址具有全網唯一性,大家最熟悉的 IP 地址大概就是 192.168.1.1 了。
現在普遍使用的是 IPv4 協議,用 32 位二進制表示 IP 地址,但為了方便人類識別、記憶將其以 8 位為單位進行分割,共分成 4 份,每份之間用句點隔開,并使用十進制表示,即:點分十進制表示法,其取值范圍為 0-255。這樣看來 IP 地址有 2^32 (4294967296)個,看似很難用完,
但由于最初 IP 地址劃分保留了一些 IP 地址導致這些地址不可用,另外隨著更多用戶接入互聯網,最終在 2011 年 2 月 3 日 IP 地址被耗盡。
現在供人類選擇的就只有 IPv6 協議了,IPv6 使用 128 位表示 IP 長度,理論上可以產生 2^128 個 IP 地址,IPv6 使用 8 組 4 個十六進制數表示地址,如:1027:0cd6:7aa3:16f3:3329:4c6e:a360:4637。
IP 地址根據應用場景通過改變網絡號和主機號的范圍進行了分類,這些分類包有:A 類,B 類,C 類,D 類,E 類,我們常用的是前三者,下圖是分類方法(以 B 類 IP 為例):
網絡號可以表示網絡的數量,主機號則是每個網絡下的主機數量,
- A 類地址,其 IP 取值范圍是:0.0.0.0 - 127.255.255.255,網絡號為地址第一段號碼,后面的三段為主機號。
- B 類地址取值范圍是:128.0.0.0 - 191.255.255.255,前兩段為網絡號,后兩段為主機號,如上圖所示。
- C 類地址取值范圍是:192.0.0.0 - 223.255.255.255,前三段為網絡號,最后一段為主機號。
根據這種分類可以看出由 A 到 C 網絡數量逐漸變多,主機數量逐漸變少,對應的應用場景為大型網絡、中型網絡,小型網絡。
一臺計算上會同時運行多個不同的網絡應用,比如 SMTP,FTP,HTTP 等,他們都處于一個 IP 地址下,因此就需要一種標識來告訴傳輸層接收到的數據要送到應用層的哪個具體應用中,這個標識就是端口號,端口號是一種虛擬的邏輯上的端口劃分,這樣做的好處是可以使各個應用合理的使用網絡資源。
端口號有 16 位,即可以表示 65536 個端口,這些端口其中一部分是被固定分配給指定的應用,比如 HTTP 占用 80 端口,SMTP 占用 25 端口。
我們在做測試時可以在 Windows 命令行中輸入 netstat -ano 命令來查看此時被占用的端口,避免發生端口沖突。
四、ARP 協議(IP 到 MAC地址的轉換)
在前面已經知道了 IP 是識別一臺計算機的唯一標識,但最終操作數據的還是網卡,所以要知道網卡的物理地址,即 MAC 地址,因此就需要一種能夠將 IP 這一邏輯標識和 MAC 地址物理標識進行轉換的協議,這種協議就是 APR 協議。大家了解其功能即可,無需深入。
五、DHCP (IP 戶口登記):動態分配 IP 地址
之前說過 IPv4 提供的 IP 資源有限,不可能為每一個人提供一個固定的 IP,因此就會導致很多人因為沒有 IP 地址而不能上網,想要解決這個問題最直接的辦法就是使用更大 IP 容量的 IPv6 協議,但是想徹底從 IPv4 過渡到 IPv6 困難重重。
因此人們想到了另外一個緩解辦法:動態分配 IP。即為了每一個設備分配一個臨時的 IP,當一個設備關機后這個空閑
的 IP 地址就會分配給其他主機使用,一個主機開機就會請求路由器為其隨機分配一個可用 IP,這樣就使得原本短缺的 IP 資源動態的流動起來,使其使用效率大大提高。
我們稱這種方式為 DHCP(Dynamic Host Configuration Protocol)。
在一個主機剛開機時,由于沒有 IP 地址,它會通過 DHCP 協議外廣播,請求該網絡內的 DHCP 主機(路由器)為其分配一個 IP,當 DHCP 主機收到這個請求后會在可用的 IP 中選擇一個并廣播出去,有 IP 地址的計算機會忽略這種廣播,只有沒有 IP 地址的主機才會將該廣播接收,并將新 IP 地址為自己所用。在 Windows 操作系統中,TCP/IPv4 屬性中的自動獲得IP 地址選項就用于選用或者關閉 DHCP 功能:
如果不開啟 DHCP,則需要使用者自行指定 IP 地址,但前提是不能和該網絡中的其他主機 IP 發生沖突,如果該網絡下主機數量很多,將會使加劇這種沖突,所以一般采用 DHCP 來動態為我們主機分配 IP,避免不必要的麻煩。
六、NAT (IP 易容術)
NAT(Network Address Translation,網絡地址轉換),是另一種緩解 IP 資源短缺的方法。
我們一定有過這種經歷:無論在哪里連接 WIFI,大多數情況下上網設備分配的 IP 地址都是 192.168.x.x,該類地址稱之為 私有地址。
在每個網絡分類中都指定了某一 IP 地址范圍為私有地址,如
A 類 IP 的私有 IP 地址范圍是:10.0.0.0~10.255.255.255,
B 類 IP 的私有 IP 地址是:172.16.0.0~172.31.255.255,
C 類 IP 私有 IP 地址是:192.168.0.0~192.168.255.255。
這類私有地址是不會被外網承認的,因此就無法上網,通常將這類私有地址作為家庭或者公司的局域網來使用,然后通過路由器進行上網,而實現這一功能的就是由路由器中的 NAT 協議來實現的,NAT 會將局域網內的主機 IP 和端口號替換成路由器的公網 IP 和端口號,然后再將數據發送給目標主機或服務器,因此在效果上來看就好像是擁有公網 IP 的路由器發出的數據一樣,從而實現了內網向外網的穿透,這么做的好處是可以使 IP 地址(私有地址)得到最大程度的復用,有效緩解 IP 資源的枯竭。
另外 NAT 的一個好處是,它可以隱藏局域網內的聯網設備,因為對于外網設備來說他們看到的只是路由器的公網 IP,其內部局域網內的主機他們是察覺不到的,因此可以提高網絡的安全性。
大家不要將 NAT 和 DHCP 這兩個概念混淆在一起,就以家庭網絡為例,NAT 功能和 DHCP 功能都由路由器提供,路由器通過 DHCP 可以為每一個剛接入到該網絡的設備按照某種策略隨機分配一個局域網 IP,如:192.168.1.23,此時該設備想要向外網發送數據,路由器就需要通過 NAT 將數據包中的局域網 IP 和端口號轉換成公網的 IP 和端口號實現外網訪問。
如果想將路由器的某一個端口接收到的數據映射到指定的該局域網內的主機上,我們可以設置路由器的端口映射來滿足要求,但是現在很多運營商為用戶分配的動態 IP 也都是局域網,也就是說在我們路由器的上一層還有一臺路由器,除非我們可以更改上一層路由器的端口映射,否則映射就會失敗。另外外網 IP 是動態的,因此每次開機的 IP 地址都可能不同,如果將我們的計算機作為服務器(比如個人論壇或者網頁)的話,那么在用戶每次訪問時就需要不停的更改 IP,顯然不切實際。因此可以選擇一些能夠提供內網穿透的服務商來為我們提供內網穿透服務,比如作者常用的就是花生殼,大家可以免費注冊和使用,對于開發調試來說已經足夠了,而且會為用戶分配一個域名(后面講解),之后設置內網和外網的映射 IP 和端口號即可:
例如我希望用自己的電腦作為物聯網的服務器,來接收各個設備發送過來的數據,則根據上圖配置,我們的物聯網設備連接的服務器地址和端口號是 18h212253o.iok.la:22958,而作為服務器的(本臺電腦)地址和端口號要設置 192.168.31.238:5468,當設備向外網 IP 發送數據時就會將這些數據映射到服務器主機上了。
花生殼具體的操作流程如下:
七、DNS 和域名(IP 綽號)
雖然使用四段點分十進制來表達 IP 地址相對于二進制表示來說更加直觀一些,但是依然不能表達特殊的人類可以理解的含義,因此就產生了域名(也叫網址),域名可以理解為一個 IP 地址的綽號,這個綽號更符合人類的記憶方式,這一點類似于電話本中的聯系人,聯系人的手機號碼對應的就是 IP 地址,聯系人的備注對應的就是域名,例如 www.fengmeitech.club(域名)就比 101.200.130.235(IP)更好記。
我們可以在 Windows 命令行中輸入 nslookup “域名”,如 nslookup www.baidu.com 來解析域名對應 IP 地址。下圖是測試結果:
當一臺計算機要訪問指定域名的主機或者服務器,如訪問 www.fengmeitech.club 時,就需要解析該域名對應的 IP 地址,因為最終的訪問對象就是 IP 地址,這時就要用到 DNS(Domain Name System,域名解析系統),當需要進行域名解析時,計算機會向 DNS 服務器發送請求解析指令,該指令是通過 UDP 協議實現,這樣的速度更快,DNS 服務器上存儲的是 IP 和域名的對應關系表,如果查到域名后將返回域名對應 IP 地址給我們的計算機,此時計算機開始訪問目標主機或者服務器。
更詳細的流程是:當計算機要訪問一個域名,此時它先從本地緩存查找是否存在這個域名,如果有,就把本地保存的域名對應 IP 提取出來然后直接訪問,如果沒有則會向你的網絡提供商(ISP,如:網通,電信等)的 DNS 服務器發出查找指令,如果 ISP 的 DNS 服務器也沒有這個域名,則 ISP DNS 服務器會向其他 DNS 服務器(根服務器,頂級服務器等)發送
解析指令,當這些 DNS 服務器解析之后找到了這個域名對應的 IP,就會將這個 IP 傳給 ISP 的 DNS 服務器,ISP 的 DNS 服務器再將找到了這個 IP 返回給你的電腦,同時 ISP 的 DNS 服務器會將這個域名 IP 對應關系緩存起來,不用下次再進行查找,到此整個的域名解析就完成了。
樂鑫 ESP8266 官方 AT 指令為我們提供了域名解析指令(AT+CIPDOMAIN=”域名”),效果如下:
接下來講解一下域名的分類,域名分類可以很好的將域名進行管理,通過查看域名可以快速獲悉域名性質,所屬上級域名等信息。域名分類采用了樹狀圖的形式進行分類,下面就以作者母校——沈陽化工大學官網(http://www.syuct.edu.cn/)為例進行講解。
在最頂層的根域名服務器(無名稱,可以用.表示,我們平時會忽略這個.)下面的是頂級域名,接著是二級域名,三級域名……主機名,頂級域名按照性質分為兩種,一個是國家頂級域名(如:中國(.cn),美國(.us),英國(.uk)等等),另一個是國際頂級域名(如:營利組織性質的.com,非盈利組織的.org),二級域名由國家劃分,按照性質分為兩種,一種是按照地理位置劃分的各省域名,如 ln.(遼寧)bj.(北京)以及按照職能性質分的 gov.(政府),edu.(教育)等。下圖是以沈陽化工大學官網為例繪制的樹狀圖:
可以看到域名從左到右依次為三級域名-二級域名-頂級域名。
八、TCP 和 UDP
前面做了這么多的鋪墊主要是為了講解 TCP 和 UDP 并對 TCP/IP 協議有一個清晰的認識。在物聯網應用中,絕大部分的硬件設備和服務器的通信方式都是基于 TCP 或者 UDP 的(少數使用 HTTP),一般情況下,TCP 應用的比 UDP 要多一些。下面來講解一下 TCP 和 UDP 的原理、特點以及區別,我們目的并不是學會這兩個協議是如何實現的,而是要知道他們的大致機理并學會應用。
8.1、TCP 協議
TCP(Transmission Control Protocol,傳輸控制協議)是一種面向連接的、安全可靠的、基于字節流的傳輸層通信協議,在進行 TCP 傳輸時,要有一方作為服務器端(Server),一方作為客戶端(Client),服務端用于監聽來自其他客戶端發來數據,一個服務端可以同時監聽多個客戶端,因此物聯網應用中,硬件設備作客戶端,服務器作為服務端。一個 TCP 的客戶端要和服務器端進行通信,客戶端就必須先指定服務器端的 IP 地址和端口號,然后通過 3 次握手建立連接,如下圖:
當握手成功后,客戶端和服務器端就正式建立了連接,此時就可以互相傳輸數據了,通常我們還會人為的對這些數據進行標識和加密,目的是保證數據傳輸安全,通過這些標識可以讓服務器來區分該數據消息來自于哪個用戶的哪臺設備,加密則是防止物聯網設備被惡意攻擊,對于能夠產生物理影響的物聯網設備來說,安全是最重要的,否則設備被攻擊后,攻擊者會惡意控制家中設備,比如打開煤氣一段時間后點燃,其后果不堪設想。
前面介紹了 TCP 的兩個階段:握手建立連接 - 數據收發,最后一個是斷開連接,通常由客戶端發起,斷開連接要經過 4 次確認,如下圖所示:
從上面來看,TCP 類似于平時撥打電話,如果想要正常通信,就必須先向指定的目標撥號,撥通并建立連接后開始通話,通話結束后由一方斷開連接。
到這里就已經介紹完了 TCP 的三個通信過程,另外我們可能都聽說過 TCP 長連接和 TCP 短連接,TCP 長連接是指客戶端和服務端長時間保持連接,這種情況在客戶端連接數量很多時會增加服務器的負擔,但是可以保證數據能夠實時的傳輸。另外一種稱為 TCP 短連接,即通信完之后立即斷開,比如常見的 HTTP 協議,因為當客戶端請求完數據之后,就不在需要繼續保持 TCP 連接了,因此可以斷開,降低服務器的工作負擔。
在物聯網應用中通常使用的都是 TCP 長連接,對于大多數物聯網應用來說對傳感器數據采集的實時性要求不高,因此間隔都比較長,比如快則幾十秒,慢則幾小時,同時這樣也可以減輕服務器的處理負擔,但是為了保證雙方連接有效,通常物聯網設備會每隔幾秒或者更長的時間發送一個簡短的數據包給服務器,證明自己還在,我們稱這種數據包為心跳包,如果服務器長時間沒有收到某一個設備發來的心跳包,則認為其斷開連接,就會將和它的TCP 連接斷開,并釋放資源,同時在用戶界面顯示該設備異常。
8.2、UDP 協議
UDP(User Datagram Protocol,用戶數據報協議)是一種簡單的面向數據報的傳輸層協議,它與 TCP 的傳輸不同,雙方不存在所謂的客戶端和服務端,只要一方知道另一方的 IP 地址和端口號,就可以直接建立連接并發送數據,并且也沒有 TCP 一系列的傳輸安全措施,比如丟包重傳和擁塞控制等,因此相對于 TCP 來說,UDP 的傳輸是不安全的,可能會出現丟包的現象,但正因為沒有了握手,數據傳輸安全等處理,使得 UDP 的傳輸速度更快,UDP 通常應用在允許丟包但要保證通信速度的場合,比如流媒體。而像文件傳輸就需要使用 TCP,因為文件傳輸的前提是保證數據的完整。但是 TCP 和 UDP 通信速度的區別我們其實是察覺不到的,只不過都是相對而言,同樣,UDP 丟包率也沒有想象中的那么嚴重,像大家平時用的 QQ 都是通過 UDP 來進行傳輸的,所以完全可以放心的將 UDP 應用到物聯網項目中,只不過使用 UDP 傳輸缺少一種連接上的控制。
到這里 TCP/IP 的基礎知識就講完了,關于這部分只要求大家了解它的用途就可以了,如果想要繼續深入學習 TCP/IP 的原理,推薦大家閱讀《圖解 TCP/IP》
總結
以上是生活随笔為你收集整理的一文详解 TCP/IP 协议的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机很多术语都是cat,18 个开源翻
- 下一篇: Kafka配置kerberos安全认证