本文對計算機網絡通訊的原理進行簡單的介紹
首先從網絡協議分層的概念進行介紹,而後對TCP、IP協議族進行了概念講解,而後對操做系統關於通訊抽象模型進行了簡單介紹,最後簡單描述了socket
分層的概念
基本概念
TCP/IP協議族自己很複雜,本人也暫時尚未「詳解TCP/IP」的想法,本系列相關的文章都是意在從宏觀上創建一個認知。
想要理解TCP/IP協議族,核心就是要理解分層的概念。
到底什麼是分層?
假如說有A,B這麼兩個部門,每一個部門有一個經理和一個祕書,有一些事情不必開會或者直接交流,好比文件的簽署,多是這樣的:
A經理拿一份文件給a祕書,而後a祕書將文件交給b祕書,b祕書而後又交給B經理,B經理簽字後,又依次經過b祕書,a祕書,最後到達A經理處
如上圖所示,藍色和紅色箭頭表示實際通過的路徑
可是對於A經理來講,他在乎的確定是文件被B經理簽字,B經理在乎的確定是簽字後的文件到達A經理處;
對於祕書們來講也是如此,他們不會直接對接經理,他們對接的是相對應的祕書;
因此,對於經理這一層次來講,他們如同直接跟對方經理交流,下層(祕書)向上層透明的提供服務,a祕書具體是如何將文件交給b祕書的,面對面交付?郵寄交付?這些經理纔不會關心,從這個角度能夠認爲,下層(祕書)對上層(經理)提供了透明的服務,上層只須要關注下層提供正確的服務便可。
因此,
分層就是層層交付,下層向上層提供服務(好比基層領導向上級領導彙報工做,上級領導繼續向上級領導彙報工做,直到中央領導....)
對於上層來講,如同兩個對等層之間直接交流,他們不關心底層的細節與實現,底層的存在是透明的
若是你只是爲了完成任務而調用別人提供的接口,你除了數據的正確性之外,你關心實現細節麼?
爲何要分層?
首先說,計算機網絡(整個計算機科學)幾乎沒有什麼事情是先有成熟的理論,而後再有完整(完美)的實現,這麼循序漸進的事情,大多數都是實踐促進理論發展,理論讓實現更完美。
世界各地運行着各類各樣的不一樣的計算機、通訊設備、網絡線路等等,網絡環境很是複雜,如何可以造成大一統的完整方案?顯然是很是困難的,若是有一種協議在各類網絡環境中都能很好的工做,那不就是萬能協議了?
好比說若是從南京到拉薩,若是全程只讓你選擇一種交通工具,應該很難或者說沒有任何一種選擇在各個路段上都是最佳選擇。
最佳的選擇就是在不一樣的路段上,選擇最合適的出行方式,好比從家坐地鐵到機場,而後坐飛機,而後火車......
網絡協議分層也是這個理念,既然環境那麼複雜,那咱們就分層處理,不一樣層次實現不一樣的任務,負責向上層正確交付。
TCP/IP層次結構
TCPIP分層介紹
如上圖所示,現有的TCP、IP協議是分層次的。
在分層體系結構中,各層之間是徹底獨立的,某一層並不須要知道他的下一層是如何實現的,而僅僅是須要知道下層提供的服務
因爲每一層都只是實現一種相對獨立的功能,於是能夠將一個難以處理的複雜問題分解爲若干個小問題。
應用層
應用層是體系結構中的最高層,應用層是經過應用進程間的交互來完成特定網絡應用。
應用層協議定義的是應用進程間通訊和交互的規則。這裏的進程就是主機中正在運行的程序。
應用層交互的數據單元稱之爲
報文
運輸層
運輸層爲兩臺主機之間的通訊提供通用的數據傳輸服務,應用進程利用該服務傳輸傳送應用層報文
運輸層
提供通用的服務,也就是說
不針對特定的網絡應用,而是
多種應用可使用同一個傳輸層服
務。
運輸層主要兩種協議
傳輸控制協議
TCP (Transmission Control Protocol)—提供面向鏈接的、可靠的數據傳輸服務,其數據傳輸的單位是報文段
用戶數據報協議
UDP (User Datagram Protocol)—提供無鏈接的、盡最大努力(best-effort)的數據傳輸服務(不保證數據傳輸的可靠性),其數據傳輸的單位是用戶數據報。
網際層
網際層負責爲分組交換網上的
不一樣主機提供通訊服務。
在發送數據時,網際層
把運輸層產生的報文段或用戶數據報封裝成分組或包進行傳送。
在TCP/IP體系中,因爲網際層使用IP協議,所以分組也叫作IP數據報,或簡稱爲數據報
網絡層的另外一個任務就是要
選擇合適的路由,使源主機運輸層所傳下來的分組,可以經過網絡中的路由器找到目的主機。
網絡接口層
TCP/IP模型中並無對網絡接口層進行準確地定義,僅僅要求可以經過網絡設備傳輸IP數據包,也就是爲IP數據報的發送和接收服務
網絡接口層
至關於OSI模型中的數據鏈路層和物理層
數據鏈路層一般簡稱爲鏈路層,兩臺主機數據傳輸,老是要通過一段段的鏈路,這就須要使用專門的鏈路層協議
在兩個相鄰節點之間傳送協議時,
鏈路層將網絡層傳遞過來的IP數據報封裝成幀,在兩個相鄰的鏈路上傳遞幀
每一幀包括數據和必要的控制信息
在接收消息時,控制信息可以提供足夠的信息讓接收端可以識別一個幀從哪一個比特開始到哪一個比特結束。
這樣鏈路層收到數據以後,就能夠提取出來數據部分,上交給網絡層。
而物理層規定了數據在物理媒體上傳遞的一些協議,好比電纜的插頭應該有多少引腳,在物理層上傳輸的是比特。
在每層中,又都運行着不一樣的協議
從這一點也更好的能看得出來,分層設計的好處,每一層均可以根據本層的特色,使用不一樣的軟硬件方案,從而既靈活又高效。
上層和下層的關係,就如同經理和祕書,祕書向經理層提供服務;而各層次中運行的協議就比如a祕書是如何將文件交給b祕書同樣,是面對面交付?仍是郵寄?這就是同一層次中的協議的概念。
快遞包裹的分層運輸
下圖爲以前淘寶時一個快遞的軌跡
賣家做爲
發送方,將
商品打包(小箱子)註明收件人信息,地址+姓名+電話。
當地的快遞點會進行
收件,收件後會
統一裝箱(大箱子)發到公司
公司會
裝車發往
下一站轉運中心
通過1個或者多個轉運中心,期間可能
通過一次或者屢次的裝車、卸車過程,
到達目的地轉運中心
從最近的轉運中心
卸車,將車內貨物發往指定公司
公司繼續將
大箱子拆解,
發往不一樣的營業廳
營業廳的
快遞員將一件或者多件快遞
送到指定地址(地址多是一個公司,多是一個小區,也多是一個學校,絕大多數地址通常都不能肯定一我的)
最終
根據電話號碼聯繫最終的收件人進行收件
這就完成了整個運輸的過程。
整個過程當中,只有寄件人和收件人知道運輸的究竟是什麼東西
從寄件人處的營業廳,到當地公司,到轉運中心,再到收件人相關的轉運中心,再到當地公司,再到最終營業廳
是
一個不斷裝箱,裝車,卸車,拆箱的過程,他們對具體的貨品徹底不知道,僅僅負責運輸。
快遞被分解爲多個階段,或者說是多個不一樣層次進行運輸
網絡數據的分層運輸
如上圖所示,計算機網絡中,數據的傳輸也是相似快遞運輸的過程。
- 應用層對應着操做系統中運行的各種應用軟件
- 傳輸層、網際層以及網絡接口層對應着操做系統、網卡、網卡驅動程序。
- 而中間的網際層、網絡接口層又對應着路由器、交換機等通訊設備
最終實現了計算機兩個進程的通訊。
聊QQ時,你腦子裏面應該沒有路由器這個東西,你感受到的應該只是你在跟對方聊QQ
也就是你在你電腦上聊天窗口中輸入內容,對方的QQ窗口中間就會接到消息,因此說下層對上層就是透明的。
網絡協議是屬於標準、規範、綱領,計算機操做系統中能夠實現所須要的功能,路由器、交換機等網絡設備中也會實現所須要的部分功能;
儘管網絡協議分層明確,可是協議是協議,實現是實現,在具體的實現上,在實現上每每是有交織的。
你沒辦法說「XXX設備只是實現了哪一層」,好比三層交換機就是具備部分路由器功能的交換機
在快遞的運輸過程當中,在全部的節點上不斷地進行着裝箱,裝車,卸車,拆箱的過程,直到貨物到達收件人手中。
在計算機網絡通訊中,數據從應用層準備好以後,相似裝箱的過程,不斷地進行封裝,添加TCP頭部,添加IP頭部,添加MAC頭部,不斷轉發,到達最終的接收方。
包的格式
包的基本結構爲頭部和數據,每一層的包(段)都是如此,上一層的數據到下一層變爲數據,而後添加對應的頭部。
好比最初的快遞盒子到了卡車上,應該是被裝到袋子(箱子)裏面,變成了數據,而後這個袋子(箱子)也會被貼上下一站的標籤。
層層包裝與運輸
以下圖所示,最初的應用層數據(賣家發出的快遞盒子),被放到了運輸層,添加TCP頭部(放入編織袋,貼上新的標籤)
而後又進入到網際層,添加了IP頭部(相似將指定目的地的貨搬上車運輸),而後又進入到鏈路層,添加MAC頭部,最終到達目的地
因此,網絡數據的傳遞,跟快遞的層層邏輯,有很大的類似性。
層次功能簡介
應用層是應用之間通訊的協議
好比,在軟件X中,咱們約定若是我發了GET三個字母給你,你就把你的某個內容回傳給我,這就是應用層的協議。
從數據傳輸交換的角度看,應用層並不涉及數據傳輸,應用層產生的數據,是被運輸的「貨物」。
運輸層真正的完成了數據端到端的傳送---從一臺計算機的一個端點傳輸到另外一臺計算機中的一個端點
網絡中有不少計算機,每一臺計算機中能夠同時運行多個應用程序
如同同一個公司地址,能夠有不少收件人
將消息傳送到某一臺計算機的某個應用程序,這就是端到端的傳送,相似經過地址+姓名手機惟必定位一個收件人
運輸層僅僅運行於主機上,並不會運行於網絡傳輸設備上,好比路由器,他們都不涉及運輸層協議
從數據真正運輸的角度看,起最大做用的是網際層,將數據從一臺計算機傳輸到另外一臺計算機的整個過程。
網際層將傳輸層數據進一步封裝,在網絡上進行傳遞,也是路由器須要的協議
經過網際層能夠肯定數據報的方向,可是具體的傳輸仍是要依靠物理設備,因此網絡接口層(鏈路層物理層)負責每一段的具體轉發。
總結下就是:
- 應用層產生數據,而且註明收件人地址、姓名電話
- 運輸層將數據進行封裝,添加TCP頭,真正開始打包運輸,至關於收件
- 網絡層將數據運送到目的主機
- 接收方的運輸層又負責將數據運送到指定程序
- 目的程序解讀數據按照應用層協議進行響應
網絡接口層完成了每一段物理鏈路上數據的傳送,網際層完成了發送方主機到接收方主機數據的傳送
運輸層在大門口接收到了數據解析後,將數據運送到指定程序
應用層讀取數據
計算機網絡的各層以及其協議的集合,就是網絡的體系結構,而網絡的體系結構是計算機網絡通訊的概念理論
是抽象的協議概念,而實現是具體的,是真正的運行在計算機中的硬件和軟件
操做系統與網絡通訊
協議說的再好聽,終歸也仍舊是協議,你講加一個TCP頭部,頭部內容是XXX....,那麼落實到最具體,多是這樣子:
你可能有一個結構體對應的是TCP格式的報文,而後你malloc一段內存空間,將接收到的數據放入這段內存中,而後計算頭部,將頭部數據進行設置......(我就是隨便說說)
因此,這纔是通訊的實現,因此說,計算機網絡就是各類設備對網絡協議的各部分的實現以及對接。
通訊依賴的是相關的硬件設備(路由器、交換機、甚至計算機)以及運行其上的實現了各部分協議的軟件,簡言之,通訊依賴的就是硬件+軟件。
對於網絡設備的硬件的製造以及協議實現是華爲、思科那種大廠關注的範疇,有N多程序猿默默地付出
而對於通常的應用程序員來講,咱們首先會關注的就是如何編寫網絡程序?
對絕大多數程序猿來講,都是面向某個編程語言進行程序開發,而編程語言中最終須要依賴於操做系統底層提供服務。
假設說,Java提供了一個方法「爆炸」,調用這個方法,電腦真的會爆炸麼?恐怕不會,由於計算機以及操做系統就沒有這個功能。
因此咱們須要瞭解下操做系統對通訊的支持。
操做系統自己也是一種軟件,負責管理計算機硬件資源,是應用程序與計算機硬件之間的中間層,將應用程序與計算機硬件解耦。
進程是通訊的實體
一個程序的運行須要操做系統提供各類資源,好比CPU時間片,主存,IO設備等
應用程序都依賴操做系統,操做系統提供了應用程序運行時各類資源的管理分配以及維護
那麼操做系統如何描述一個「程序的運行」?
進程就是操做系統對「程序的運行」進行抽象,對一個運行中的程序的描述
不少事物,當咱們須要對他們進行識別管理時,最經常使用的方法就是編號,1號電腦,2號電腦;1號門,2號門等等
進程也不例外,進程ID(英語:processID)、PID)是大多數操做系統的內核用於惟一標識進程的一個數值。
因此說,在操做系統中,對於一個正在運行的程序,但是藉助於進程ID---PID進行惟一標識。
由於計算機能夠運行多個應用程序,因此,計算機的通訊基本都是指應用程序間的通訊
那麼既然進程是一個程序運行的標識,就能夠說是兩個進程之間的通訊
TCP/IP的應用
隨着操做系統的發展,1983年,TCP/IP被Unix 4.2BSD系統採用。
隨着Unix的成功,TCP/IP逐步成爲Unix機器的標準網絡協議。
也就是說操做系統內置了網絡通訊的功能,而且是按照TCP/IP協議實現的。
所謂的採用也就是用程序代碼按照TCP/IP的邏輯實現了兩個應用程序相互通訊的功能
因此,在操做系統中談論TCP/IP協議時,咱們能夠假想兩個程序模塊,一個TCP模塊,一個IP模塊,分別負責TCP和IP協議的實現
爲了簡單,甚至能夠理解成就兩個方法,一個叫tcp()一個叫ip()
tcp()接收到應用層的數據後,添加相應頭部,而後交給ip(),添加ip相關頭部。
端口
經過一個IP地址就能夠惟一的定位到一臺主機,在經過進程號不就能夠惟一肯定一個應用程序麼
可是事實恐怕不能如此,試想一下通訊的過程
你說:「我但願和ip地址爲xxx.xxx.xxx.xxx的主機的yyy進程進行通訊」
想要通訊天然要先知道ip地址,可是進程號是接收方操做系統對於接受信息的應用程序的描述,是操做系統內部的數據
並且,是動態分配的,就好像你一下子叫張三,一下子叫李四,我怎麼跟你通訊?
因此就出現了「端口」的概念,能夠認爲是計算機與外界通信交流的出口
「端口」的概念將計算機進程與外界的聯繫進行解耦
好比21分配給ftp服務使用,外界想要使用該主機的ftp服務,只須要向21號端口發送請求便可,不須要關注提供ftp服務的應用程序的Pid
ftp服務程序只須要到21號這個窗口「接貨」就行了
端口有三種類型
1.周知端口(Well Known Ports)
周知端口是衆所周知的端口號,範圍從0到1023
其中80端口分配給WWW服務,21端口分配給FTP服務等。
咱們在IE的地址欄裏輸入一個網址的時候是沒必要指定端口號的,由於在默認狀況下WWW服務的端口是「80」。
2.動態端口(Dynamic Ports)
動態端口的範圍是從49152到65535。之因此稱爲動態端口,是由於它 通常不固定分配某種服務,而是動態分配。
3.註冊端口
端口1024到49151,分配給用戶進程或應用程序。
這些進程主要是用戶選擇安裝的一些應用程序,而不是已經分配好了公認端口的經常使用程序。
這些端口在沒有被服務器資源佔用的時候,能夠用用戶端動態選用爲源端口。
發起請求的客戶端,不用關心本身的端口號,只須要將端口號告知接收端便可
可是客戶端必需要知道接收端的端口號,這樣才能與對方計算機的某一個應用程序進行通訊。
因此說,一個計算機上的端口,是對外界打開的窗戶。
操做系統的通訊模型
說到這,瞭解了「進程、操做系統對TCP/IP的實現、端口」咱們能夠整理下操做系統對通訊的處理邏輯:
一臺計算機中會運行多個程序,咱們使用進程的概念對程序進行標識,可是進程是計算機內部的標識,如何才能提供給外部?因此有了端口的概念,端口就至關於分機號。
而操做系統對於TCP/IP的實現,就是基於這樣一種模式,實現了端到端的通訊(也就是進程間的通訊)
簡單點說就是操做系統具有了端到端通訊的功能,經過IP地址定位到主機,經過端口號定位到進程(某個運行中的應用程序)
socket編程接口
有了端口號和IP地址,咱們就能夠惟一的肯定一臺主機的一個應用程序了
那麼, 也就是說有了這麼一對「端口號和IP地址」
發送方的IP地址和端口號,以及接收方的IP地址和端口號,咱們就能夠經過網絡進行通訊
這就至關於一個精確到XXX小區XXX棟樓XXX號的一個地址,是通訊過程當中的兩個端點,如同賣家的店鋪和你的房子
這樣一個端點,有一個有意思的名字,叫作
socket 套接字
TCP協議就是提供端到端的通訊
socket本意是插座,TCP協議將兩個端點鏈接起來,即插即用,用插座來形容很形象
操做系統實現TCP/IP協議的目的是爲了計算機通訊,而計算機通訊的目的也是爲了計算機中的應用程序進行通訊
若是沒有任何的應用程序,那麼計算機網絡的意義也很小了
操做系統都會提供標準的編程接口,以供應用程序調用系統服務,操做系統對TCP/IP的實現也不例外,針對於操做系統實現的TCP/IP協議,也提供了對應的接口 ,以便應用程序能夠藉助於操做系統,實現網絡互連
這個編程接口API也叫作socket,因此,網絡編程有時也被稱爲socket編程
socket是實現過程當中,應用層程序和操做系統傳輸層程序的一箇中間層,他並不屬於網絡協議的一部分
Socket 起源於Unix WINDOWS下也有一套socket規範
socket是對TCP/IP協議的封裝,複雜的TCP/IP協議族隱藏在Socket接口後面
它的出現使得程序員可以更加方便地藉助於TCP/IP協議棧通訊
想一下在平時的編碼中,常常會出現這樣一種狀況:
對某些經常使用場景,將基礎功能單元的方法進行進一步封裝,提升使用的便利性
Socket 就至關於進一步封裝後的方法
簡言之,socket簡化了使用TCP/IP的複雜程度。
必定程度上,能夠將socket理解爲外觀模式(門面模式)
門面模式的意圖:
「爲子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這一接口使得這一子系統更加易於使用。」
從門面模式中應該能更容易理解,socket是實現層面上,應用層與傳輸層的中間層。
總結
計算機網絡將數據的傳輸進行分層,從而將複雜的問題進行簡化
每一層僅僅關注當前層的交互邏輯,經理僅僅關注文件的簽署狀況
應用層僅僅關注應用之間的交流方式,運輸層負責端到端的應用,網際層負責網絡上兩個主機之間的傳輸,鏈路層物理層負責將IP報文在物理設備上進行轉發
- 網際層和網絡接口層(鏈路層和物理層)僅僅是負責轉發,純屬送貨的
- 運輸層至關於收發室,最後一步
- 應用層纔是目的地
經過計算機操做系統以及網絡設備對協議的實現,最終構成了完整的計算機網絡。
計算機實現了通訊功能,而且提供了編程接口,因此對於程序員來講,一眼望過去只是socket編程接口,至於底層的複雜的TCP/IP的實現細節,徹底不須要關注
插入socket這一編程接口層的目的也很顯然,能夠簡化開發的複雜程度
原本很複雜的網絡通訊程序的設計與開發,通過層層的封裝,轉換成了只須要面向socket編程便可,比起前人,你是否是幸福太多?
參照上面網絡數據在不一樣協議層之間的傳輸,有了socket,應用程序之間的網絡通訊編程,就只須要面向socket編程便可。
大大的下降了網絡編程的成本,從socket API往下就如同不存在同樣,這一般被叫作「透明」,透明的存在,好比一塊高透的玻璃,看起來不就如同不存在同樣麼
因此想要作一個合格的程序員,須要着眼於應用層和Socket接口層,想要成爲一個優秀的程序員,須要對底層有一個更深刻的瞭解。