- title: 網絡基礎學習總結(1)
- tags: 網絡
- categories:筆記
- date: 2017-06-18 17:40:54
做web開發呢,除了前端后端技術要熟練使用外,想要更進一步學習web原理,那必須還得了解計算機網絡的一些基礎知識。計算機網絡范圍其實很廣,內容雜多。說來慚愧啊,上學時候,上課都沒有認真思考,實驗也沒有充分發揮主觀能動性,浪費了現有硬件資源來對網絡進行更深的學習。但是,在日常工作中,對這些原理的東西也不能一概不知。就打算來說說,網絡中的一些基礎內容,包括:數據傳輸模型OSI,TCP/IP,TCP協議的建立與釋放,IP數據報的傳輸與數據格式等等。
網絡通信模型
因為從計算機整個發展到現在的歷程來看,從沒有操作系統的單太計算機,只是用于數據簡單處理的計算機,到后來的批處理系統,多道程序系統,到分時系統,實時系統的發展,計算機處理能力呈現爆炸性增長,伴隨著處理能力提升,早起不同的計算機公司開發自己定義的計算機系統以及計算機通信協議,導致了不同的公司或者說不同的硬件底層支持的計算機的通信會很復雜,硬件的異構型造成了計算機通信的成本花費很大。特別是萬維網的創建,更是將整個實驗室,縣城,市區到國家之間的計算機通信互聯的現實需求推至頂端。
那么為了不同公司,不同類型的計算機進行通信更高效,方便,那么無規矩不成方圓。權威機構當然就聯合起來,共同定制合理有效的計算機通信模型以及協議等等。也是適應時代發展的需要和推動計算機互聯網的快速發展的必然結果。
OSI參考模型
該模型定義了不同計算機互聯的標準,是設計和描述計算機網絡通信的基本框架。開放系統互聯參考模型的系統結構共分7層。在該模型中層與層之間進行對等通信,且這種通信只是邏輯上的,真正的通信都是在最底層-物理層實現的,每一層要完成相應的功能,下一層為上一層提供服務,從而把復雜的通信過程分成了多個獨立的、比較容易解決的子問題。--引用自百度OSI
下面這張圖,把整個OSI協議模型以及每層協議棧上的一些協議給列出來了:(圖片來源自網絡)
該OSI通信框架知道有7層,那七層,每層大致做得什么,有什么作用就夠了。在此就不細說了。
TCP/IP參考模型
TCP/IP參考模型是計算機網絡的祖父ARPANET和其后繼的因特網使用的參考模型。ARPANET是由美國國防部DoD(U.S.Department of Defense)贊助的研究網絡。逐漸地它通過租用的電話線連結了數百所大學和政府部門。當無線網絡和衛星出現以后,現有的協議在和它們相連的時候出現了問題,所以需要一種新的參考體系結構。這個體系結構在它的兩個主要協議出現以后,被稱為TCP/IP參考模型(TCP/IP reference model)。 --百度
這個TCP/IP參考模型有四層:網絡訪問層、網際互聯層、傳輸層(主機到主機)、和應用層。(圖片引用自網絡)
兩種模型的比較
共同點
(1)OSI參考模型和TCP/IP參考模型都采用了層次結構的概念。
(2)都能夠提供面向連接和無連接兩種通信服務機制。
不同點
(1)OSI采用的七層模型,而TCP/IP是四層結構。
(2)TCP/IP參考模型的網絡接口層實際上并沒有真正的定義,只是一些概念性的描述。而OSI參考模型不僅分了兩層,而且每一層的功能都很詳盡,甚至在數據鏈路層又分出一個介質訪問子層,專門解決局域網的共享介質問題。
(3)OSI模型是在協議開發前設計的,具有通用性。TCP/IP是先有協議集然后建立模型,不適用于非TCP/IP網絡。
(4)OSI參考模型與TCP/IP參考模型的傳輸層功能基本相似,都是負責為用戶提供真正的端對端的通信服務,也對高層屏蔽了底層網絡的實現細節。所不同的是TCP/IP參考模型的傳輸層是建立在網絡互聯層基礎之上的,而網絡互聯層只提供無連接的網絡服務,所以面向連接的功能完全在TCP協議中實現,當然TCP/IP的傳輸層還提供無連接的服務,如UDP;相反OSI參考模型的傳輸層是建立在網絡層基礎之上的,網絡層既提供面向連接的服務,又提供無連接的服務,但傳輸層只提供面向連接的服務。
(5)OSI參考模型的抽象能力高,適合與描述各種網絡;而TCP/IP是先有了協議,才制定TCP/IP模型的。
(6)OSI參考模型的概念劃分清晰,但過于復雜;而TCP/IP參考模型在服務、接口和協議的 區別上不清楚,功能描述和實現細節混在一起。
(7)TCP/IP參考模型的網絡接口層并不是真正的一層;OSI參考模型的缺點是層次過多,劃分意義不大但增加了復雜性。
(8)OSI參考模型雖然被看好,由于沒把握好時機,技術不成熟,實現困難;相反,TCP/IP參考模型雖然有許多不盡人意的地方,但還是比較成功的。
-- 引用自百度
數據通信
在了解了現代計算機之間的數據通信模型后,就可以來具體看看計算機之間是如何進行數據傳遞的,在傳遞過程中會遇到什么問題,數據是以什么樣的形式進行封裝傳輸的。若是在傳輸中出現錯誤,又是如何進行處理的。其實,有很多問題值得我們思考并進行更深層次的理解與代碼開發。
因為數據的傳輸大致就是兩種:WLAN廣域網內的計算機互聯通信以及LAN局域網內的主機進行互聯通信。所以其實數據的產生和傳輸都是需要硬件支持的,若是能了解一些常見的計算機網絡硬件如:網絡交換機,路由器,集線器等,還有以太網技術和VLAN虛擬局域網,可能會更能加深對整個數據通信過程的理解把。有些硬件中對協議通信的支持能力很高,智能的接收數據,轉發數據等等,有些則是常規的數據轉發推送等。
數據封裝解封流程
因為,從上面模型可以知道。數據的傳輸過程中,需要經過不同層次的協議棧,那么每個層次對傳輸的數據是如何處理的呢?[以以太網網絡為背景]
其實,在實際數據的通信傳輸過程中,在發送端:每層協議棧都會在上層協議的基礎上,添加本層的頭數據或者尾部添加數據。并且,每層添加的協議頭部的數據結構其實也是不一樣的,因為不同層次的協議棧有不同的處理作用,就造成了有不同的需求,所以協議頭當然是不同的。直到封裝數據到最后成以太網幀(在以太網中),在硬件設備和網絡中進行數據傳送。
在接收端:因為發送端在發送數據會進行協議層封裝,那么接收端就是解封裝。根據每次協議層的規則,拆分協議頭數據進行記錄和處理。直到最后將發送端的應用程序,發送有效數據傳輸到接收端的具體應用中,進行數據處理。
因為不同層次的協議會對數據處理處理,所以,每個對每個層次的數據的稱呼也就不一樣了:
物理層: 比特(bit)
鏈路層: 幀(Frame)
網絡層: 分組數據包(Packet)
傳輸層: 數據段(Segment)
上述兩端的數據通信流程可以通過圖示更加形象的表現處理:
【TCP/IP參考模型】
可以看到,從最頂層的應用程的用戶數據的產生,傳輸到下層TCP,會對數據進行TCP首部封裝成段數據(segment),在往下層網絡層傳輸,該層會添加IP首部,這時候數據就變成了分組數據包,再往下就是主機到以太網的連接層,封裝成以太網幀(frame),添加以太網首部,尾部等等。最后就可以將整個數據發送到網絡中。
在大致了解了網絡總計算機的數據通信要經過基層協議棧的處理封裝,到最后數據傳輸,再到數據解封到接收端的過程后,就可以對每層的協議進行了解了,看看,每個層次的協議數據結構是怎樣的,每層協議的封裝的協議頭部有什么用,以及每個層次協議棧中有哪些常見的協議,都可以進行了解和學習。
TCP協議棧
在傳輸層中,主要的協議就是TCP以及UDP協議,前者是面向連接的字節流可靠的數據通信協議;后者是無連接的不可靠的協議。其實,這兩種協議在實際應用中都很廣泛,并且內部內容還不少。這里因為是基礎知識內容學習,就打算只是講講tcp協議內容。
什么是TCP(Transmission Control Protocol),可以查看百度TCP。通過名字知道它是傳輸控制協議。就是在主機通信過程中,在傳輸層對數據進行控制處理的協議。這個面向連接的可靠服務的協議,功能還不少,包括數據正確性校驗,超時重傳,窗口流量控制等等。這些功能都是為了支持可靠性而服務的。
TCP數據段數據格式
【1】那么,在傳輸層中,tcp段數據的內部格式是怎么樣的?如下圖:
可以看到,tcp數據在ip數據包中的位置,以及整個tcp段數據的數據格式。
【2】根據上圖的數據段的數據格式,每個位置的字段內容代表什么?
- 源端口和目的端口號: 這兩個字段均為16位長度,表示發送端和接收端的端口,用于確認發送端和接收端的應用程序。發送端的IP地址和端口號以及接收端的IP地址和端口號可以確認一個在internet上的TCP連接(端對端的連接建立)。(PORT + IP : 定位主機與主機上的應用程序)
- 序列號: 序列號是一個32位長度字段,表示分配給TCP包的編號。序列號用來標識應用程序從TCP的發送端到接收端發送的字節流。當TCP開始連接的時候,發送一個序列號給接收端,連接成功后,這個序列號作為初始序列號ISN。之后連接成功發送的第一個字節的序列號位ISN+1,之后發送數據ISN將按照字節的大小進行遞增,當序列號大于2的32次方-后,從0開始。
- 確認號: 發送方對發送的首字節進行了編號,當接收方成功接收后,發送接收成功的序列號加1標識確認回發送端,發送方再次發送的時候就從這個返回的確認號開始。(三次握手)
- 頭部長度: 表示TCP頭部的長度,由于TCP的數據有可選字段,頭部長度用于表示頭部的長度。該項長度位4位,單位是32位字長的數據。TCP的頭部最長為60字節,如果沒有可選字段通常是20個字節。
- 保留位: 6位長度沒有使用,必須設置為0.
- ** 控制位**: 6位長度的控制位,可以多個位一起設置。含義如下表:
字段 含義
URG 緊急指針字段
ACK 表示確認號有效
PSH 表示接收方需要盡快將此數據交給應用層
RST 重建連接
SYN 用于發起一個TCP連接
FIN 用于表示將要斷開TCP的連接
- 窗口尺寸: 窗口的尺寸也稱作接收窗口大小,<u>表示本機上TCP協議可以接收的以字節位單位的數目</u>,本字段為16位長度。
- TCP校驗和: 16位長度,用于校驗TCP傳輸數據的正誤,包括TCP頭和所有數據,TCP的數據必須強制校驗。
- 緊急指針: 16位長度,只有設置了URG位為1這個字段數據才會有效,他指出了緊急接收數據的字節的順序編號。
- 選項: 經常使用的為最大分段長度MSS。tcp連接通常在第一個通信的報文中指明這個選項,它指明當前主機所能接收的最大報文長度。
【3】TCP在linux中代碼定義:
為了校驗或者說從程序員的角度來理解這個TCP協議,最直接的方式就是通過底層代碼的方式來看了。那么,在linux系統中,對tcp的定義確實可以看到。
可以查看cat /usr/include/linux/tcp.h
可以看到具體的對tcp的數據格式的定義:
#ifndef _LINUX_TCP_H
#define _LINUX_TCP_H
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/socket.h>
struct tcphdr {
__be16 source; /*源地址端口*/
__be16 dest; /*目的地址端口*/
__be32 seq; /*序列號*/
__be32 ack_seq; /*確認序列號*/
#if defined(__LITTLE_ENDIAN_BITFIELD) /*小端對齊*/
__u16 res1:4, /*保留*/
doff:4, /*偏移(頭部長度)*/
fin:1, /*關閉連接標志*/
syn:1, /*請求tcp連接標志*/
rst:1, /*重置連接標志*/
psh:1, /*接收方盡快將數據推送至應用層*/
ack:1, /*確認序列號標志*/
urg:1, /*緊急指針標志*/
ece:1, /*擁塞標志位*/
cwr:1; /*擁塞標志位*/
#elif defined(__BIG_ENDIAN_BITFIELD) /*大端對齊*/
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__be16 window; /*滑動窗口大小*/
__sum16 check; /*校驗和*/
__be16 urg_ptr; /*緊急字段指針*/
};
/*
* The union cast uses a gcc extension to avoid aliasing problems
* (union is compatible to any of its members)
* This means this part of the code is -fstrict-aliasing safe now.
*/
union tcp_word_hdr {
struct tcphdr hdr;
__be32 words[5];
};
根據上面的tcp端數據的數據格式和上述代碼定義結合起來理解,可以發現代碼就是按照tcp的數據段的數據格式內容來進行定義的,只不過是區分了內存存儲字節的大端對齊還是小端對齊的方式而已。
TCP連接與釋放
在理解了傳輸層協議棧中tcp協議數據段的內部數據格式,以及格式中每個字段代表的內容。接下來就可以來看看一個tcp連接是如何連接和釋放的。沒錯,就是大名鼎鼎的TCP三次握手和四次揮手。
【1】TCP三次握手
在廣域網或者局域網內,兩臺主機要進行tcp的連接,數據交互,都必須遵循TCP/IP協議模型中tcp連接規則:TCP三次握手。
即tcp是面向字節流的連接,在確認兩個主機可以進行tcp交互的前提是,tcp鏈路連接必須要在數據交互前建立起來。
TCP三次握手,其實就是TCP連接建立的過程,三次握手的目的是同步連接雙方的序列號和確認號并交換TCP窗口大小信息。
因為兩臺主機要進行tcp數據交互,對于每單獨的主機,你得知道雙發對于數據包發送的規則,即從那個包開始發送,有什么標志說明某個數據是第一次發送的數據,什么時候你發送過來的數據是結束數據?每次你那邊能接收到多少字節的數據?所以,三次握手就是為了數據交互做探測準備的。
下面來分別說說這個TCP三次握手的細節流程:【主要的就是同步序列號和確認號】
客戶端主機A主動打開,發送連接請求報文段(segment),將tcp連接標志為SYN值為1,表示要發起一個連接;將seq(序列號:分配給報文段的編號標志)設置為x(TCP規定SYN=1時不能攜帶數據,x為隨機產生的一個值),然后客戶端狀態進入SYN_SEND。
服務器端B收到A發送過來的報文,進行確認處理,表示收到的序列號有效,設置ACK=1;因為也要發送一個請求連接進行返回,所以SYN=1;因為服務器端B也要發送報文段數據,所以設置報文序列號為seq=y(這個服務器端B主機的報文段序列號,也是為了客戶機A接收到,加1處理設置確認序列號返回用的),這時候,最重要的是設置確認序列號ack,因為在第一步中接收到了主機A發送的序列號x,這時候,接收端需要在接收到的序列號基礎上加1,將值x+1作為確認序列號設置到tcp報文段中,所以設置ack=x+1。
表示:我已經收到發來的序列號了,確認序列號為x+1,你下次發送報文段數據的序列號就從x+1開始設置,這樣,我才認可是你發送的數據,才是有效數據。。客戶端主機A接收服務器端的反饋數據,進行再次確認,若是得到的ack為第一次發送的序列號基礎上加1,那么說明這個報文段是有效的,設置ACK=1;因為不是要求重新發送tcp請求,所以,不用在設置SYN=1了。只是需要校驗確認序列號,這邊確認成功,還要對接收到的服務器端序列號y進行設置,在y基礎上加1,將y+1作為確認序列號設置到報文段的ack字段中,為了讓服務器端進行報文校驗,即設置ack=y+1(當B端接收到報文段后,獲取ack=y+1,說明與上次發送的報文序列號差1,報文段有效),因為確認報文有效了,所以,此時可以將這個發送的報文段的序列號設置為接收來的確認序列號seq=x+1,說明,正式的數據發送已經開始了,從x+1開始的序列號的報文段就是我發送的。
seq序列號表示發送的報文段的報文編號,ack序列號表示對方接收端處理后的確認序列號,用于校驗報文段是否正確的。
在三次握手建立好連接之后,就可以進行正常的數據交互了,當然了,每次數據交互發送的報文段都是又這些例如序列號seq,接收方的確認序列號,控制表示,源和目的端口號等等。
為什么客戶端要進行二次確認?
因為會出現已失效的連接請求報文情況:
正常來說,客戶端發出連接請求,但因為連接請求報文丟失而未收到確認。于是客戶端再次發出一次連接請求,后來收到了確認,建立了連接。數據傳輸完畢后,釋放了連接,客戶端一共發送了兩個連接請求報文段,其中第一個丟失,第二個到達了服務端,沒有"已失效的連接請求報文段"。
現在假定一種異常情況,即客戶端發出的第一個連接請求報文段并沒有丟失,只是在某些網絡節點長時間滯留了,以至于延誤到連接釋放以后的某個時間點才到達服務端。本來這個連接請求已經失效了,但是服務端收到此失效的連接請求報文段后,就誤認為這是客戶端又發出了一次新的連接請求。于是服務端又向客戶端發出請求報文段,同意建立連接。假定不采用三次握手,那么只要服務端發出確認,連接就建立了。
由于現在客戶端并沒有發出連接建立的請求,因此不會理會服務端的確認,也不會向服務端發送數據,但是服務端卻以為新的傳輸連接已經建立了,并一直等待客戶端發來數據,這樣服務端的許多資源就這樣白白浪費了。
采用三次握手的辦法可以防止上述現象的發生。比如在上述的場景下,客戶端不向服務端的發出確認請求,服務端由于收不到確認,就知道客戶端并沒有要求建立連接。
【2】TCP四次揮手
當兩段AB的tcp連接傳輸完成之后,要進行斷開,就像tcp連接要進行三次握手才能正確的傳遞數據;在tcp的斷開也要進行一些規則的流程:<font color="red">TCP四次揮手</font>。
再來看看tcp四次揮手的流程圖:
揮手流程分析:
客戶端A主機在得到或者處理完成數據需求之后,就準備關閉連接了,先會發送一個報文給服務器端B主機(沒有數據),設置報文控制位FIN=1
,要求斷開連接。該報文序列號seq設置位u,seq=u,客戶端在將該報文發送出去后,就進入FIN_WAIT_1狀態。服務器端B主機收到了來自客戶端的請求后,校驗確認序列號后設置ACK=1,同時也設置響應報文序列號seq=v,并將接收到的客戶端的報文的序列號+1作為確認序列號,即設置ack=u+1,放回給客戶端主機A,此時服務器端進入了CLOSE_WAIT狀態。(因為步驟一中客戶端A的斷開請求又多種情況,主動權也是在客戶端主機A,那么就會又這種狀況,服務器主機B的應用處理還沒又完成,就收到客戶端的斷開請求,這時候在響應客戶端說,服務器收到了斷開請求,準備斷開后,進入close_wait狀態后,就要通知服務器端的處理程序,要進行斷開了,至于怎么處理就要看程序的控制了。響應請求未發送FIN控制位值)
當通知完服務器端的應用程序,要進行關閉后,服務器端就會被動關閉,就會發送一個斷開請求,FIN=1,并根據上次發送響應報文的確認序列號u+1,又設置同樣的值,這樣,就說明這此FIN斷開請求與上次響應請求是一致的,并同時設置確認序列號有效ACK=1,設置該次請求報文序列號seq=w。這個時候,服務器端進入LAST_ACK狀態,即最后一次發送確認序列號。(這次請求是服務器端關閉應用程序后,在被動關閉的狀態下發送的斷開連接請求。)
客戶端第二次接收到服務器端信息(但是是第一次接收服務器端FIN斷開連接請求),即從報文段中知道FIN=1,即服務器請求斷開連接了,客戶端就會進入TIME_WAIT狀態,接著發送一個確認報文,校驗收到的服務器端的FIN斷開請求,設置ACK=1,報文序列號設置為客戶端的第二次發送,即在第一次發送的seq=u的基礎上再加1,即seq=u+1,同時ack將會設置為從服務器端B主機接收的報文序列號w的基礎上加1,ack=w+1,表明接收到了斷開請求且確認序列號有效。最后,服務器端和客戶端都會進入CLOSE_WAIT狀態。
為什么握手只要三次,揮手卻要四次?
因為服務端在LISTEN狀態下,收到建立請求的SYN報文后,<u>把ACK和SYN放在一個報文里發送給客戶端</u>。而連接關閉時,當收到對方的FIN報文時,僅僅表示對方沒有需要發送的數據了,但是還能接收數據,己方未必數據已經全部發送給對方了,所以己方可以立即關閉,也可以將應該發送的數據全部發送完畢后再發送FIN報文給客戶端來表示同意現在關閉連接。【LAST_ACK表示沒有數據要發送了】
從這個角度而言,再斷開連接的時候,<u><font color="red">服務端的ACK和FIN一般都會分開發送</font></u>。
IP協議棧
在TCP/IP參考模型中的網際層中的IP協議棧,在數據傳輸過程中,會對上層的tcp處理后的數據段(segment),在此進行封裝,加上自己的ip頭部數據。
其中,雖然arp,icmp協議并不是該層的協議,但是兩者在該層中是與ip協議進行協同工作的。即IP層中包含網際控制報文協議和地址識別協議。
前者ICMP用于報告網絡上的某些出錯情況,允許網際路由器傳輸出現差錯信息或者測試報文。
后者ARP處于IP層和數據鏈路層之間,它是用來將32位ip地址與MAC地址轉換用的。
關于ip更詳細的介紹,參考百度-ip
IP數據包數據格式
好了,在簡要介紹了網際層的常見協議和作用外,就可以看看該層的數據包中的數據格式和內部字段代表的含義。
【1】數據包數據格式
可以看到,相比較TCP的數據段內的數據格式,ip內部的數據也不少。
【2】字段含義
根據上面一步中的IP數據包內部數據格式,下面可以來分別看看內部的字段分別代表了什么意思。
- 版本號:ip協議的版本號,長度4位,規定網絡實現的IP版本。IPV4該值為4。
- 首部長度: 首部長度指的是IP字段除去數據的整個頭部數據長度,是以32位的字作為計算單位。最短的IP頭部長度是20字節,最長為60個字節。所以該屬性值的可取值范圍是5 - 15。
- 服務類型(TOS): ip服務類型字段長度8位。包括3位優先權,4位T服務類型子字段和1位保留字段:
字段 優先權 D T R F 保留
長度 3位 1位 1位 1位 1位 1位
含義 優先級 延遲 吞吐量 可靠性 費用 未用
其中:后四位字段只能用一個,若是全部為0表示一般服務。服務類型字段由應用程序進行設置,路由器僅在必要的時候進行讀取,不會進行設置。
- 總長度:總長度字段長度16位,表示以字節為單位的數據報文長度,長度包含IP頭部和數據部分。 所以ip數據報文總長度可以到達65535個字節長度。
- 標識和片偏移: IP每次發一份數據報文都會填寫一個標識用來表示此數據包,發送完后此值會加1。所以,在傳輸數據>mtu=1500個字節的時候,需要對數據報文進行分片。在分片的時候,需要對分片的每一個數據設置序號和ip報文來源,都可以在標識種進行設置。還要加上分片數據在源數據報文種的偏移地址,便于接收端收到所有分片的ip數據報進行重新組合。
-
生存時間: TTL(time to live) 字段的值表示數據報文最多可以經過的路由器的數量。源主機發送數據時候設置TTL(一般為32或者64),沒經過一個
路由器進行分轉,TTL的值減一。當TTL=0的時候,路由器會丟棄此包,并發送一個ICMP報文通知源主機。目的: 防止在數據報傳輸過程種出現錯誤,引起包在Internet的路由器之間不斷循環,因而加入TTL機制限制報文經過的路由總數。 - 協議類型: 該字段為8位長度,即最多可以表示255種協議類型,表示IP上承載的是什么高級協議。目的是為了在網際層種進行封包和解包的過程中,TCP/IP協議棧知道將這些數據包發給那個層的協議棧做相關的處理。協議類型含義如下表:
值 協議類型
1 ICMP
2 TCP
6 IMGP
17 UDP
...
-
頭部檢驗和: 校驗和是一個16位長度數值。使用循環冗余校驗生成,其作用是保證IP幀的完整性。發送端發送數據的時候要計算CRC16校驗值,填寫到此
字段中;接收端會計算IP的校驗值并與該字段進行匹配,如果不匹配表示幀發生錯誤,將丟棄此報文。因為CRC16的計算與TTL有關,所以每次經過路由器都要重新計算。 - 源地址和目的地址: 即為發送端和接收端主機的ip地址。
【3】ip數據包在linux中代碼定義:
若是像查看ip數據包在linux中代碼的定義情況,則可以通過命令cat /usr/include/linux/ip.h
查看:
/*IP頭部數據結構的定義*/
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD) /*小端對齊*/
__u8 ihl:4, /*ip頭部長度,單位是32bit*/
version:4; /*IP版本,值為4 IPV4*/
#elif defined (__BIG_ENDIAN_BITFIELD) /*大端*/
__u8 version:4, /*版本 ipv4*/
ihl:4; /*IP頭部長度*/
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos; /*服務類型*/
__be16 tot_len; /*總長度*/
__be16 id; /*數據報標識*/
__be16 frag_off; /*分片數據片偏移量*/
__u8 ttl; /*生存時間*/
__u8 protocol; /*協議類型:tcp,udp,icmp,imgp*/
__sum16 check; /*頭部校驗和*/
__be32 saddr; /*源主機ip地址*/
__be32 daddr; /*目的主機ip地址*/
/*The options start here. */ /*ip選項*/
};
可以根據代碼中,定義的變量與ip數據包數據格式中字段進行對比就可以知道,代碼的編寫中變量的定義就是參考ip數據包格式來的。
以太網
在發送端,數據通過應用層到傳輸層,網際IP層,最后越是貼近物理層,封裝成以太網幀(以太網中)進行傳輸。再來看看這個幀內部信息。
以太網幀數據格式
【1】以太網幀數據格式如下圖:
可以看到,以太網幀的數據格式挺簡單的。包括以太網頭部中的:目的mac,源mac,類型。mac代表當前主機和通信主機的硬件地址。類型,則是用于表明當前幀是什么類型的數據幀,是ip數據包,還是arp請求等等。后面還有個以太網尾部CRC,4個字節用來做循環冗余校驗的。
其中,通過以太網幀中的數據長度46~1500,就涉及到一個概念MTU,也就是最大傳輸單元,表明單個幀數據最多能傳輸1500個字節數據(不包括頭部數據)。
【2】幀在linux代碼中的定義:
若是想查看linux中,是如何對以太網幀進行代碼定義的話,可以通過命令cat /usr/include/linux/if_ether.h
來查看,可以看到幀的全部字段和類型數據:
#ifndef _LINUX_IF_ETHER_H
#define _LINUX_IF_ETHER_H
#include <linux/types.h>
/*
* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
* and FCS/CRC (frame check sequence).
*/
#define ETH_ALEN 6 /* Octets in one ethernet addr 以太網地址:mac地址 */
#define ETH_HLEN 14 /* Total octets in header. 以太網頭部的總長度:源地址+目的地址+數據類型 */
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS 不含CRC校驗的數據最小長度:46+12+2 */
#define ETH_DATA_LEN 1500 /* Max. octets in payload 幀內數據的最大長度MTU*/
#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS 不含CRC校驗和的最大以太網數據長度*/
#define ETH_FCS_LEN 4 /* Octets in the FCS CRC校驗和字段長度*/
/*
* These are the defined Ethernet Protocol ID's.
下面定義的是以太網頭部中類型字段選址:代表不同的數據類型 2個字節 2^16種類型
*/
#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
#define ETH_P_TSN 0x22F0 /* TSN (IEEE 1722) packet */
#define ETH_P_IP 0x0800 /* Internet Protocol packet 表示IP數據報文 */
#define ETH_P_X25 0x0805 /* CCITT X.25 */
#define ETH_P_ARP 0x0806 /* Address Resolution packet ARP協議數據類型*/
#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */
#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */
#define ETH_P_BATMAN 0x4305 /* B.A.T.M.A.N.-Advanced packet [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
#define ETH_P_LAT 0x6004 /* DEC LAT */
#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
#define ETH_P_CUST 0x6006 /* DEC Customer use */
#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
#define ETH_P_TEB 0x6558 /* Trans Ether Bridging */
#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
#define ETH_P_ATALK 0x809B /* Appletalk DDP */
#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
#define ETH_P_IPX 0x8137 /* IPX over DIX */
#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
#define ETH_P_PAUSE 0x8808 /* IEEE Pause frames. See 802.3 31B */
#define ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */
#define ETH_P_WCCP 0x883E /* Web-cache coordination protocol
* defined in draft-wilson-wrec-wccp-v2-00.txt */
#define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */
#define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */
#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
#define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */
#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
* over Ethernet
*/
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
#define ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */
#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
#define ETH_P_TIPC 0x88CA /* TIPC */
#define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */
#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
#define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */
#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
#define ETH_P_NCSI 0x88F8 /* NCSI protocol */
#define ETH_P_PRP 0x88FB /* IEC 62439-3 PRP/HSRv0 */
#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
#define ETH_P_TDLS 0x890D /* TDLS */
#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */
#define ETH_P_80221 0x8917 /* IEEE 802.21 Media Independent Handover Protocol */
#define ETH_P_HSR 0x892F /* IEC 62439-3 HSRv1 */
#define ETH_P_LOOPBACK 0x9000 /* Ethernet loopback packet, per IEEE 802.3 */
#define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_QINQ3 0x9300 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_AF_IUCV 0xFBFB /* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
#define ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is less than this value
* then the frame is Ethernet II. Else it is 802.3 */
/*
* Non DIX types. Won't clash for 1500 types.【MTU】
*/
#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
#define ETH_P_802_2 0x0004 /* 802.2 frames */
#define ETH_P_SNAP 0x0005 /* Internal only */
#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
#define ETH_P_CAN 0x000C /* CAN: Controller Area Network */
#define ETH_P_CANFD 0x000D /* CANFD: CAN flexible data rate*/
#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */
#define ETH_P_CONTROL 0x0016 /* Card specific control frames */
#define ETH_P_IRDA 0x0017 /* Linux-IrDA */
#define ETH_P_ECONET 0x0018 /* Acorn Econet */
#define ETH_P_HDLC 0x0019 /* HDLC frames */
#define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */
#define ETH_P_DSA 0x001B /* Distributed Switch Arch. */
#define ETH_P_TRAILER 0x001C /* Trailer switch tagging */
#define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */
#define ETH_P_IEEE802154 0x00F6 /* IEEE802.15.4 frame */
#define ETH_P_CAIF 0x00F7 /* ST-Ericsson CAIF protocol */
#define ETH_P_XDSA 0x00F8 /* Multiplexed DSA protocol */
/*
* This is an Ethernet frame header.
*/
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr 以太網目的Mac地址 */
unsigned char h_source[ETH_ALEN]; /* source ether addr 以太網源MAC地址*/
__be16 h_proto; /* packet type ID field 以太網包類型:16位*/
} __attribute__((packed));
#endif /* _LINUX_IF_ETHER_H */
硬件設備
不同層次對應的硬件配置:(通常情況下,不包括三層交換機,四層交換機..)
物理層:網卡,網線,集線器,中繼器,調制解調器
數據鏈路層:網橋,交換機
網絡層:路由器
網關工作在第四層傳輸層及其以上
集線器是物理層設備,采用廣播的形式來傳輸信息。
交換機就是用來進行報文交換的機器。多為鏈路層設備(二層交換機),能夠進行地址學習,采用存儲轉發的形式來交換報文.。
路由器的一個作用是連通不同的網絡,另一個作用是選擇信息傳送的線路。選擇通暢快捷的近路,能大大提高通信速度,減輕網絡系統通信負荷,節約網絡系統資源,提高網絡系統暢通率。
交換機和路由器的區別?
交換機擁有一條很高帶寬的背部總線和內部交換矩陣。交換機的所有的端口都掛接在這條總線上,控制電路收到數據包以后,處理端口會查找內存中的地址對照表以確定目的MAC(網卡的硬件地址)的NIC(網卡)掛接在哪個端口上,通過內部交換矩陣迅速將數據包傳送到目的端口,目的MAC若不存在則廣播到所有的端口,接收端口回應后交換機會“學習”新的地址,并把它添加入內部MAC地址表中。
使用交換機也可以把網絡“分段”,通過對照MAC地址表,交換機只允許必要的網絡流量通過交換機。通過交換機的過濾和轉發,可以有效的隔離廣播風暴,減少誤包和錯包的出現,避免共享沖突。
交換機在同一時刻可進行多個端口對之間的數據傳輸。每一端口都可視為獨立的網段,連接在其上的網絡設備獨自享有全部的帶寬,無須同其他設備競爭使用。當節點A向節點D發送數據時,節點B可同時向節點C發送數據,而且這兩個傳輸都享有網絡的全部帶寬,都有著自己的虛擬連接。假使這里使用的是10Mbps的以太網交換機,那么該交換機這時的總流通量就等于2×10Mbps=20Mbps,而使用10Mbps的共享式HUB時,一個HUB的總流通量也不會超出10Mbps。
總之,交換機是一種基于MAC地址識別,能完成封裝轉發數據包功能的網絡設備。交換機可以“學習”MAC地址,并把其存放在內部地址表中,通過在數據幀的始發者和目標接收者之間建立臨時的交換路徑,使數據幀直接由源地址到達目的地址。
從過濾網絡流量的角度來看,路由器的作用與交換機和網橋非常相似。但是與工作在網絡物理層,從物理上劃分網段的交換機不同,路由器使用專門的軟件協議從邏輯上對整個網絡進行劃分。例如,一臺支持IP協議的路由器可以把網絡劃分成多個子網段,只有指向特殊IP地址的網絡流量才可以通過路由器。對于每一個接收到的數據包,路由器都會重新計算其校驗值,并寫入新的物理地址。因此,使用路由器轉發和過濾數據的速度往往要比只查看數據包物理地址的交換機慢。但是,對于那些結構復雜的網絡,使用路由器可以提高網絡的整體效率。路由器的另外一個明顯優勢就是可以自動過濾網絡廣播。
**集線器與路由器在功能上有什么不同? **
首先說HUB,也就是集線器。它的作用可以簡單的理解為將一些機器連接起來組成一個局域網。而交換機(又名交換式集線器)作用與集線器大體相同。但是兩者在性能上有區別:集線器采用的式共享帶寬的工作方式,而交換機是獨享帶寬。這樣在機器很多或數據量很大時,兩者將會有比較明顯的。而路由器與以上兩者有明顯區別,它的作用在于連接不同的網段并且找到網絡中數據傳輸最合適的路徑。路由器是產生于交換機之后,就像交換機產生于集線器之后,所以路由器與交換機也有一定聯系,不是完全獨立的兩種設備。路由器主要克服了交換機不能路由轉發數據包的不足。
總的來說,路由器與交換機的主要區別體現在以下幾個方面:
(1)工作層次不同
最初的的交換機是工作在數據鏈路層,而路由器一開始就設計工作在網絡層。由于交換機工作在數據鏈路層,所以它的工作原理比較簡單,而路由器工作在網絡層,可以得到更多的協議信息,路由器可以做出更加智能的轉發決策。
(2)數據轉發所依據的對象不同
交換機是利用物理地址或者說MAC地址來確定轉發數據的目的地址。而路由器則是利用IP地址來確定數據轉發的地址。IP地址是在軟件中實現的,描述的是設備所在的網絡。MAC地址通常是硬件自帶的,由網卡生產商來分配的,而且已經固化到了網卡中去,一般來說是不可更改的。而IP地址則通常由網絡管理員或系統自動分配。
(3)傳統的交換機只能分割沖突域,不能分割廣播域;而路由器可以分割廣播域
由交換機連接的網段仍屬于同一個廣播域,廣播數據包會在交換機連接的所有網段上傳播,在某些情況下會導致通信擁擠和安全漏洞。連接到路由器上的網段會被分配成不同的廣播域,廣播數據不會穿過路由器。雖然第三層以上交換機具有VLAN功能,也可以分割廣播域,但是各子廣播域之間是不能通信交流的,它們之間的交流仍然需要路由器。
(4)路由器提供了防火墻的服務
路由器僅僅轉發特定地址的數據包,不傳送不支持路由協議的數據包傳送和未知目標網絡數據包的傳送,從而可以防止廣播風暴。
該部分截取自:OSI七層模型詳解
總結
上面的內容僅僅是網絡的很小很小的基礎知識部分,也是自己學習過程中一些總結。包括數據通信的OSI/TCP參考模型,并對數據通信中每層的協議棧進行分析和內部數據結構的圖解,同時也將linux系統對每層協議的代碼定義也羅列出來,幫助程序員加深理解。其實,內部還有很多東西值得去學習,分析,思考。這篇就到這....
[圖片上傳失敗...(image-84c371-1511017700608)]
參考:
Liux網絡編程(第二版)
TCP:三次握手、四次握手、backlog及其他