計算機網絡 : 網絡基礎
目錄
- 計算機網絡 : 網絡基礎
- 引言
- 1. 網絡發展背景
- 2. 初始協議
- 2.1 初始協議
- 2.2 協議分層
- 2.2.1 軟件分層的好處
- 2.2.2 OSI七層模型
- 2.2.3 TCP/IP五層(四層)模型
- 2.3 `TCP/IP`協議
- 2.3.1`TCP/IP`協議與操作系統的關系(宏觀)
- 2.4 網絡傳輸基本流程
- 2.4.1 局域網網絡傳輸流程(以太網)
- 2.4.2 數據包封裝和分用
- 2.4.3 跨網絡傳輸流程
- 3. Socket編程預備
- 3.1 認識端口號
- 3.2 傳輸層的典型代表
- 3.3 網絡字節序
- 3.4 `socket`編程接口
引言
本博客將系統介紹計算機網絡的基礎知識,包括網絡的發展背景、核心協議(如TCP/IP
)、協議分層模型(OSI與TCP/IP
)、網絡傳輸流程(局域網與跨網絡通信)以及Socket
編程的基本概念。無論你是初學者還是希望鞏固基礎的技術愛好者,都能從這里獲得清晰的網絡知識框架和實踐指導。
1. 網絡發展背景
-
獨立模式:計算機之間相互獨立
-
網絡互聯:多臺計算機連接在一起,完成數據共享
-
局域網LAN:計算機數量更多了,通過交換機和路由器連接在一起
-
廣域網WAN:將遠隔千里的計算機都連在了一起
-
所謂局域網和廣域網都只是一個相對的概念。
-
計算機是人的工具,人要協同工作,就注定計算機中網絡的產生是必然的。
-
網絡的發展一直都是從局部到整體。而整體記性通信靠的是
ip
地址,網絡中一切皆IP
。
2. 初始協議
2.1 初始協議
-
協議是一種約定
-
舉例:
計算機之間的傳輸媒介是光信號和電信號,通過 頻率 和 強弱 來表示 0 和 1 這樣的信息。要想傳遞各種不同的信息,就需要約定好雙方的數據格式。
思考:只要通信的兩臺主機約定好協議就可以了嗎?如果僅定好協議,但你用頻率表示 01,我用強弱表示 01,就好比我用中文,你用葡萄牙語一樣,雖然雙方可能遵守一套通信規則,但語言不同,即使訂好了基本協議,也無法正常通信。
因此,完善的協議需要更細致的規定,并確保所有參與者都嚴格遵守。計算機生產廠商眾多,操作系統和網絡硬件設備也各不相同,如何讓不同廠商生產的計算機能夠順暢通信?這就需要業界共同制定一個統一的標準,即 網絡協議。
-
通常,具備制定協議或標準資格的組織或公司必須是業界公認的權威機構。
能定制協議標準的組織或公司主要有以下幾類:
國際標準化組織:
**IEEE(電氣和電子工程師協會)**是一個由計算機和工程領域專家組成的龐大技術組織,在通信協議領域貢獻突出,制定了全世界電子、電氣和計算機科學領域約30%的標準,包括IEEE 802系列標準,涵蓋從局域網(LAN)到廣域網(WAN)等多種網絡技術。
**ISO(國際標準化組織)**由多個國家的標準化團體組成,以開放系統互連(OSI)模型著稱,該模型定義了網絡通信的七層協議結構,盡管TCP/IP協議族更常用,但OSI模型在學術和理論研究中仍占重要地位。
**ITU(國際電信聯盟)**是聯合國下屬的專門機構,負責制定電信領域的國際標準,ITU-T的標準涵蓋電話和網絡通信,與ISO合作確保全球兼容性和互操作性。
區域標準化組織:
**ETSI(歐洲電信標準學會)**由歐洲共同體各國政府資助,成員包括電信行業的廠商與研究機構,從事從研究開發到標準制定的工作。
**ASTAP(亞洲與泛太平洋電信標準化協會)**于1998年由日本與韓國發起成立,旨在加強亞洲與太平洋地區信息通信基礎設施及其相互連接的標準化協作。
公司:某些公司(如泰凌微)自研低功耗藍牙、Zigbee、Thread及Matter等標準的軟件協議棧,并可定制化改動,這是其核心競爭力之一;泰凌微還計劃重點發展智能電子價簽、智能遙控、智能家居等市場。
民間國際團體:**IETF(互聯網工程師任務組)**是負責開發和推廣互聯網協議(尤其是TCP/IP協議族)的志愿組織,通過RFC發布新協議或更新舊協議標準。
官方機構:**FCC(聯邦通信委員會)**是美國管理通信技術的官方機構,主要職責是通過對無線電、電視和有線通信的管理保護公眾利益,并對通信產品的技術特性(包括標準化)進行審查和監督。
以上組織或公司均能定制協議標準,以滿足特定需求或推動技術發展。
2.2 協議分層
- 協議本質也是軟件,在設計上為了更好的進行模塊化,解耦合,因此也是被設計成為層狀結構的。
2.2.1 軟件分層的好處
- 在這個例子中,我們的協議只有兩層:語言層和通信設備層。但是實際上的通信協議,設計的會更加復雜,層數會更多。
- 通過上面的例子,我們就可以理解,分層其實就是為了實現解耦合,讓軟件維護的成本更低
2.2.2 OSI七層模型
- OSI(Open System Interconnection,開放系統互連)七層網絡模型 稱為開放式系統互聯參考模型,是一個邏輯上的定義和規范。
- 把網絡從邏輯上分為了7層,每一層都有相關、相對應的物理設備,比如路由器、交換機。
- OSI七層模型是一種框架性的設計方法,其最主要的功能是幫助不同類型的主機實現數據傳輸。它的最大優點是將服務、接口和協議這三個概念明確地區分開來,概念清楚,理論也比較完整,通過七個層次化的結構模型使不同的系統、不同的網絡之間實現可靠的通訊。
- 在網絡角度,OSI設定的7層協議模型是非常完善的,但是在實際操作的過程中,會話層、表示層是不可能接入到操作系統中的,所以在工程實踐中,最終落地的是5層協議。不過由于它既復雜又不實用,所以我們按照TCP/IP四層模型來講解。
2.2.3 TCP/IP五層(四層)模型
-
TCP/IP 是一組協議的代名詞,它還包括許多協議,組成了 TCP/IP 協議簇。
-
TCP/IP 通訊協議采用了 5 層的層級結構,每一層都調用它的下一層所提供的網絡來完成自己的需求。
- 物理層負責光/電信號的傳遞方式,比如現在以太網通用的網線(雙絞線)、早期以太網采用的同軸電纜(現在主要用于有線電視)、光纖,以及現在的 Wi-Fi 無線網使用的電磁波等都屬于物理層的概念。物理層的能力決定了最大傳輸速率、傳輸距離、抗干擾性等,集線器(Hub)工作在物理層。
- 數據鏈路層負責設備之間的數據幀的傳送和識別,例如網卡設備的驅動、幀同步(檢測信號以確定新幀的開始)、沖突檢測(檢測到沖突時自動重發)、數據差錯校驗等工作,常見的標準包括以太網、令牌環網和無線 LAN,交換機(Switch)工作在數據鏈路層。
- 網絡層負責地址管理和路由選擇,例如在 IP 協議中,通過 IP 地址標識主機,并利用路由表規劃數據傳輸路徑,路由器(Router)工作在網絡層。
- 傳輸層負責兩臺主機之間的數據傳輸,如傳輸控制協議(TCP)確保數據可靠地從源主機發送到目標主機。
- 應用層負責應用程序間的通信,如簡單郵件傳輸協議(SMTP)、文件傳輸協議(FTP)、網絡遠程訪問協議(Telnet)等,網絡編程主要針對應用層。
物理層我們考慮的比較少,我們只考慮軟件相關的內容,因此很多時候我們直接稱為TCP/IP
四層模型。
一般而言
- 對于一臺主機,它的操作系統內核實現了從傳輸層到物理層的內容;
- 對于一臺路由器,它實現了從網絡層到物理層;
- 對于一臺交換機,它實現了從數據鏈路層到物理層;
- 對于集線器,它只實現了物理層。
但是并不絕對,很多交換機也實現了網絡層的轉發;;很多路由器也實現了部分傳輸層的內容(比如端口轉發)。
2.3 TCP/IP
協議
-
TCP/IP
協議出現的原因就是因為通信主機距離變遠了。任何通信特征的變化,一定會帶來新的問題,有問題就得解決問題,所以需要新的協議。 -
TCP/IP
協議的本質就是一種解決方案,TCP/IP
協議能分層的前提是因為問題們本身能分層。
2.3.1TCP/IP
協議與操作系統的關系(宏觀)
問題:主機 B 能識別 data,并且準確提取 a=10,b=20,c=30 嗎?
回答:答案是肯定的!因為雙方都有同樣的結構體類型 struct protocol
。也就是說,用同樣的代碼實現協議,用同樣的自定義數據類型,天然就具有“共識”,能夠識別對方發來的數據,這就是約定。
關于協議的樸素理解:所謂協議,就是通信雙方都認識的結構化的數據類型。因為協議棧是分層的,所以每層都有雙方共同遵守的協議,同層之間可以互相理解對方的協議。
2.4 網絡傳輸基本流程
2.4.1 局域網網絡傳輸流程(以太網)
-
兩臺主機在同一個局域網,是能夠直接通信的。
-
每臺主機在局域網上,要有唯一的標識來保證主機的唯一性:
mac
地址。 -
認識MAC地址
- MAC地址用來識別數據鏈路層中相連的節點。
- 長度為48位(即6個字節),通常以16進制數字加冒號的形式表示(例如:08:00:27:03:fb:19)。
- MAC地址在網卡出廠時確定且一般不能修改,通常是唯一的(但虛擬機中的MAC地址并非真實地址可能沖突,部分網卡也支持用戶配置MAC地址)。
-
局域網傳輸流程圖
- 以太網中,任何時刻,只允許一臺機器向網絡中發送數據(因為以太網本質就是共享資源具有互斥屬性);以太網中所有主機都會收到信息(泛洪)。
- 如果有多臺同時發送,會發生數據干擾,我們稱之為數據碰撞。
- 所有發送數據的主機要進行碰撞檢測和碰撞避免。
- 沒有交換機的情況下,一個以太網就是一個碰撞域。
- 局域網通信的過程中,主機對收到的報文確認是否是發給自己的,是通過目標 MAC 地址判定。
-
同一網段內的兩臺主機進行發送信息的過程
主機之間的通信:我們必須認識到,本質是兩個協議棧在通信。
而其中每層都有協議,所以當我進行上述流程過程的時候,要進行封裝和解包。
接受信息的主機中將網卡和數據鏈路層切換到混雜模式,就可以接受所有主機發送的信息,而不進行判斷是否是發送個自己的。(抓包工具的原理)
-
概念:
- 報頭部分,就是對應協議層的結構體字段,我們一般叫做報頭。
- 除去報頭部分,剩下的叫做有效載荷。
- 報文 = 報頭 + 有效載荷
-
不同層完整報文的叫法
- 不同的協議層對數據包有不同的稱謂,在傳輸層叫做段(segment);
- 在網絡層叫做數據報(datagram);
- 在鏈路層叫做幀(frame);
- 應用層數據通過協議棧發到網絡上時,每層協議都要加上一個數據首部(header),稱為封裝(Encapsulation)。
- 首部信息中包含了一些類似于首部有多長、載荷(payload)有多長、上層協議是什么等信息。
- 數據封裝成幀后發到傳輸介質上,到達目的主機后每層協議再剝掉相應的首部,根據首部中的"上層協議字段"將數據交給對應的上層協議處理。
-
-
結論:
- 在網絡傳輸的過程中,數據不是直接發送給對方主機的,而是先要自頂向下將數據交付給下層協議進行封裝,最后由底層發送,然后由對方主機的底層來進行接受,再自底向上進行向上交付。
- 自頂向下封裝的意義就是必須貫穿到操作系統,貫穿協議棧,OS是硬件(網卡)的管理者。
- 不考慮應用層協議的情況下,任何協議都滿足2點:1.報頭必須具有和有效載荷進行分離的能力。2.報頭中必須包含,如何將自己的有效載荷,交付給上層的哪一個具體協議。
- 底層收到報文,會進行判斷此報文是否是發送給自己的,如不是數據鏈路層會直接丟棄。
- 協議棧:自頂向下封裝就是協議棧將報頭入棧的過程;自下向上解包分用就是出棧的過程。
-
2.4.2 數據包封裝和分用
-
數據封裝的過程
-
數據分用的過程
-
接下來的協議學習,我們在宏觀上都應該建立一個認識:
- 要學習的協議,是如何做到解包的?只有明確了解包,封包也就能理解。
- 要學習的協議,是如何做到將自己的有效載荷,交付給上層協議的?
2.4.3 跨網絡傳輸流程
-
網絡中的地址管理——認識IP地址
- IP協議有兩個版本,
IPV4和IPV6
,本作者關于計網的博客,如沒做特殊說明,提到的IP協議默認指的是IPV4
。 - IP 地址是在 IP 協議中用來標識網絡中不同主機的地址;
- 對于 IPv4 來說,IP 地址是一個 4 字節、32 位的整數;
- 我們通常也使用"點分十進制"的字符串表示 IP 地址,例如 192.168.0.1,用點分割的每一個數字表示一個字節,范圍是 0 - 255。
- 跨網段的主機的數據傳輸,數據從一臺計算機到另一臺計算機傳輸過程中要經過一個或多個路由器。路由器會根據信息的源IP地址和目的IP地址,選擇將信息發送到哪個局域網中,通過一個或多個局域網的交接,最終信息到達目的IP地址的主機。
- 電腦和路由器我們都可以看成主機。
- IP協議有兩個版本,
-
IP地址的意義
只要有網絡層,就會有路由功能。
然后結合封裝與解包,體現路由器解包和重新封裝的特點。
-
IP地址和Mac地址的區別
- IP地址在整個路由過程中一直保持不變(目前暫作此說明,后續會修正),而MAC地址則會不斷變化。
- 目的IP地址代表通信的最終目標,是路徑選擇的主要依據;
- 而MAC地址則是下一跳的局部目標,是局域網內數據轉發的重要依據。
-
路由過程中,IP地址不變,Mac地址一直在變,Mac地址只會在本局域網內有效。
-
網絡通信的宏觀流程
-
網絡層+IP的意義就是:給網絡提供了一層虛擬化層,讓世界上所有的網絡,都叫做IP網絡,屏蔽最底層網絡的差異。
-
只要IP地址從技術上說是可以的,但是為什么還要Mac地址呢?因為網絡是從局部到整體的,是先有局域網的Mac地址再有廣域網的IP地址,如果改成只有IP地址,意味著之前的Mac地址全都要換,沒有意義,且只有IP地址會帶來數據鏈路層與網絡層的強耦合。
-
3. Socket編程預備
3.1 認識端口號
-
首先我們要達成一個共識,數據通過網絡傳輸到主機不是目的,而是手段。到達主機內部,在交給主機內的進程,才是目的。
-
但是在系統中,同時會存在非常多的進程,當數據到達目的主機之后,怎么轉發給目標進程?這就要在網絡的背景下,在系統中,表示進程的唯一性了。
-
-
端口號(
port
)是傳輸層協議的內容- 端口號是一個2字節16位的整數。
- 端口號用來表示一個進程,告訴操作系統,當前的這個數據要交給哪一個進程來處理。
- IP地址 + 端口號能夠標識網絡上的某一臺主機的某一個進程。
- 一個端口號只能被一個進程占用,但是一個進程可能有多個端口號。
-
端口號范圍劃分
0-1023
:知名端口號,HTTP、FTP、SSH等這些廣為使用的應用層協議,他們的端口號都是固定的。1024-65535
:操作系統動態分配的端口號,客戶端程序的端口號,就是由操作系統從這個范圍分配的。
-
理解端口號
port
和進程pid
進程
pid
屬于系統概念,技術上也具有唯一性,確實可以用來標識唯一的一個進程,但是不是所有的進程都要進行網絡通信,因此不是所有的進程都有端口號。并且如果pid
變化了怎么辦?歸根結底,端口號的出現就是為了對系統和網絡進行解耦。 -
理解源端口號和目的端口號
傳輸層協議(
TCP
和UDP
)的數據段中有兩個端口號,分別叫做源端口號和目的端口號。 就是在描述 “數據是哪個進程發的, 要發給哪個進程”; -
理解
socket
- 綜上,
IP
地址用來標識互聯網中唯一的一臺主機,port
用來標識該主機上唯一的一個網絡進程。 IP+Port
就能表示互聯網中唯一的一個進程。- 所以,通信的時候,本質是兩個互聯網進程代表人來進行通信,{
srcIp
,srcPort
,dstIp
,dstPort
}(源IP,源端口號,目的IP,目的端口號)這樣的4元組就能標識互聯網中唯二的兩個進程。 - 所以,網絡通信的本質,也是進程間通信。
- 我們把
ip+port
叫做套接字socket
。
- 綜上,
3.2 傳輸層的典型代表
-
如果我們了解了系統,也了解了網絡協議棧,我們就會清楚,傳輸層是屬于內核的。那么我們要通過網絡協議棧進行通信,必定調用的是傳輸層提供的系統調用,來進行的網絡通信。
-
TCP協議(Transmission Control Protocol 傳輸控制協議):有傳輸層協議;有鏈接;可靠傳輸;面向字節流。
-
UDP協議(User Datagram Protocol 用戶數據報協議):有傳輸層協議;無連接;不可靠傳輸;面向數據報。
3.3 網絡字節序
-
我們已經知道,內存中的多字節數據相對于內存地址有大端和小端之分,磁盤文件中的多字節數據相對于文件中的偏移地址也有大端小端之分,網絡數據流同樣有大端小端之分。那么如何定義網絡數據流的地址呢?
- 發送主機通常將發送緩沖區中的數據按內存地址從低到高的順序發出;
- 接收主機把從網絡上接到的字節依次保存在接收緩沖區中,也是按內存地址從低到高的順序保存;
- 因此,網絡數據流的地址應這樣規定:先發出的數據是低地址,后發出的數據是高地址。
- TCP/IP協議規定,網絡數據流應采用大端字節序,即低地址高字節。
- 不管這臺主機是大端機還是小端機,都會按照這個TCP/IP規定的網絡字節序來發送/接收數據;
- 如果當前發送主機是小端,就需要先將數據轉成大端;否則就忽略,直接發送即可。
-
為使網絡程序具有可移植性,使同樣的C代碼在大端和小端計算機上編譯后都能正常運行,可以調用以下庫函數做網絡字節序和主機字節序的轉換。
- 這些函數名很好記,
h
表示host
,n
表示network
,l
表示32位長整數,s
表示16位短整數。 - 例如
htonl
表示將32位的長整數從主機字節序轉換為網絡字節序,例如將IP地址轉換后準備發送。 - 如果主機是小端字節序,這些函數將參數做相應的大小端轉換然后返回。
- 如果主機是大端字節序,這些函數不做轉換,將參數原封不動地返回。
- 這些函數名很好記,
3.4 socket
編程接口
-
socket
常見API// 創建 socket 文件描述符 (TCP/UDP, 客戶端 + 服務器) int socket(int domain, int type, int protocol); // 綁定端口號 (TCP/UDP, 服務器) int bind(int socket, const struct sockaddr *address,socklen_t address_len); // 開始監聽 socket (TCP, 服務器) int listen(int socket, int backlog); // 接收請求 (TCP, 服務器) int accept(int socket, struct sockaddr* address,socklen_t* address_len); // 建立連接 (TCP, 客戶端) int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
-
sockaddr
結構Socket API
是一層抽象的網絡編程接口,適用于各種底層網絡協議,如IPv4
、IPv6
,以及后面要講的UNIX Domain Socket
。然而,各種網絡協議的地址格式并不相同。-
IPv4
和IPv6
的地址格式定義在netinet/in.h
中,IPv4
地址用sockaddr_in
結構體表示,包括 16 位地址類型、16 位端口號和 32 位 IP 地址。 -
IPv4
、IPv6
地址類型分別定義為常數AF_INET
、AF_INET6
。這樣,只要取得某種sockaddr
結構體的首地址,不需要知道具體是哪種類型的sockaddr
結構體,就可以根據地址類型字段確定結構體中的內容。 -
socket API
可以都用struct sockaddr *
類型表示,在使用的時候需要強制轉化成sockaddr_in
;這樣的好處是程序的通用性,可以接收IPv4
、IPv6
,以及UNIX Domain Socket
各種類型的sockaddr
結構體指針做為參數。 -
sockaddr
結構 -
sockaddr_in
結構雖然socket API的接口是
sockaddr
,但是我們真正在基于IPv4
編程時,使用的數據結構是sockaddr_in
;這個結構里主要有三部分信息:地址類型、端口號、IP地址。 -
in_addr
結構in_addr
結構用來表示一個IPv4
的IP地址,其實就是一個32位的整數。
-