since
1、網絡分層
Osi7層--------->
Tcp/ip4層
應用層:負責處理應用程序的邏輯,比如文件傳輸、名稱查詢和網絡管理等,它在用戶空間實現。通過/etc/services文件可以查看所有知名的應用層協議。
傳輸層:為兩臺主機上的應用程序提供端到端的通信,與網絡層使用的逐跳通信方式不同,傳輸層只關心通信的起始端和目的端。
網絡層:實現數據包的選路和轉發。通信的兩臺主機一般不是直接相連的,而是通過多個中間節點(路由器)連接的。網絡層的任務就是選擇這些中間節點,以確定兩臺主機之間的通信路徑。網絡層對上層協議隱藏了網絡拓撲連接的細節。
數據鏈路層:實現了網卡接口的網絡驅動程序,以處理數據在物理媒介上的傳輸。
注:TCP/IP4層協議中,ARP/RARP協議位于數據鏈路層
2、協議簡介
(1)ARP(地址解析協議)和RARP(逆地址解析協議),它們實現了IP地址和機器物理地址之間的轉換。網絡層使用IP地址尋址一臺機器,而數據鏈路層使用物理地址尋址一臺機器,因此網絡層必須先使用ARP協議將目標機器的IP地址轉換為其物理地址,才能使用數據鏈路層提供的服務; RARP協議用于網絡上的某些無盤工作站,它們利用網卡上的物理地址來向網絡管理者查詢自身的IP地址。
ARP工作原理:主機向自己所在的網絡廣播一個ARP請求,該請求包含目標機器的網絡地址。此網絡上的其它機器都將收到這個請求,但只有被請求的目標機器會回應一個ARP應答,其中包含自己的物理地址。
以太網ARP請求/應答報文的格式如下圖:
硬件類型字段定義物理地址的類型,它的值為1表示MAC地址。
協議類型字段表示要映射的協議地址類型,它的值為0x800,表示IP地址。
硬件地址長度字段和協議地址長度字段,單位是字節。
操作字段指出4種操作類型:ARP請求(值為1),ARP應答(值為2),RARP請求(值為3),RARP應答(值為4)。
最后4個字段指定通信雙方的以太網地址和IP地址。發送端填充除目的端以太網地址外的其它3個字段,以構建ARP請求并發送。接收端若發現該請求的目的端IP地址是自己的,就把自己的以太網地址填進去,然后交換兩個目的端地址和發送端地址,以構建ARP應答并返回之。
ARP高速緩存的查看和修改:
ARP維護一個高速緩存,其中包含經常訪問或最近訪問的機器的IP地址到物理地址的映射,這樣就避免了重復的ARP請求,提高了發送數據包的速度。linux下可使用arp命令刪除和添加ARP緩存。例如:arp -d 192.168.1.109(刪除對應的緩存項),arp -s 192.168.1.109 08:00:27:53:10:67(添加對應的緩存項)。
(2)ICMP(因特網控制報文協議)
如上圖,8位類型字段用于區分報文類型,它將ICMP報文分為兩大類:一類是差錯報文,用來回應網絡錯誤(目標不可達或者重定向等);另一類是查詢報文,用來查詢網絡信息(ping應用程序)。有的ICMP報文還使用8位代碼字段進一步細分不同的條件。ICMP報文使用16位校驗和字段對整個報文進行循環冗余校驗(CRC),以檢驗報文在傳輸過程中是否損壞。
(3)IP(因特網協議),根據數據包的目的IP地址來決定如何投遞它,若數據包不能直接發送給目標主機,那么IP協議就為它尋找一個合適的下一跳路由器,并將數據包交付給該路由器來轉發。多次重復這一過程,數據包最終到達目標主機,或者由于發送失敗而被丟棄。可見,IP協議用逐跳的方式確定通信路徑。
為上層協議提供無狀態、無連接、不可靠的服務
無狀態:指IP通信雙方不同步傳輸數據的狀態信息,因此所有的IP數據報的發送、傳輸和接收都是相互獨立的、沒有上下文關系的。
無連接:指IP通信雙方不長久地維持對方的任何信息,這樣,上層協議每次發送數據的時候,都必須明確指定對方的IP地址。
不可靠:指IP協議不能保證IP數據報準確地到達接收端。
Ipv4頭部結構:
(4)TCP(傳輸控制協議),為應用層提供可靠的、面向連接的和基于流的服務。
(5)UDP(用戶數據報協議),為應用層提供不可靠、無連接和基于數據報的服務。
(6)telnet(遠程登錄協議),使我們能在本地完成遠程任務。
(7)OSPF(開放最短路徑優先協議),是一種動態路由更新協議,用于路由器之間的通信,以告知對方各自的路由信息。
(8)DNS(域名服務協議),提供機器域名到IP地址的轉換。
DNS是一個分布式的域名服務系統。眾多網絡客戶端程序都使用DNS協議來向DNS服務器查詢目標主機的IP地址,其查詢和應答報文如下圖:
3、http(超文本傳送)協議詳解
它定義了瀏覽器(萬維網客戶進程)怎樣向萬維網服務器請求萬維網文檔,以及服務器怎樣把文檔傳送給瀏覽器。萬維網的工作流程如下圖所示:
用戶在點擊鼠標鏈接某個萬維網文檔時,http協議首先要和服務器建立TCP鏈接,使用三次握手,當三次握手的前兩部分完成后,萬維網客戶就把http請求報文作為三次握手的第三個報文的數據發送給萬維網服務器。服務器收到http請求報文之后,就把所請求的文檔作為響應報文返回給客戶。
http/1.0主要缺點是每請求一個文檔就要有兩倍RTT的開銷,另一個開銷是萬維網客戶和服務器每一次建立新的TCP鏈接都要分配緩存和變量,當萬維網服務器同時要服務于大量客戶的請求時,這會使萬維網服務器的負擔很重。
http/1.1解決了上述問題,它使用了持續連接,即萬維網服務器在發送響應后仍然在一段時間內保持這條連接。
http協議本身是無連接的,通信雙方在交換http報文之前不需要先建立http鏈接;http協議是無狀態的,同一個客戶第二次訪問同一個服務器上的頁面時,服務器的響應與第一次被訪問時的相同(假定現在服務器還沒有把該頁面更新),這使得服務器容易支持大量并發的http請求。
http請求報文的一些方法:
http與https的區別
https是安全超文本傳輸協議,使用的端口是443,與http的明文傳輸不同的是,它是由ssl+http協議構建的可進行加密傳輸、身份認證的網絡協議。
http狀態碼的含義表:
cookie和session的區別
cookie:
在客戶端保持狀態,將cookie附在請求資源的http請求頭上發送給服務器(不安全)(存儲的數據不可以超過4k)。
session:在服務器端保持狀態,服務器用一種類似于散列表的結構來保存信息,給客戶端返回一個session id保存于cookie,當cookie被人為禁止時,使用url重寫/表單隱藏字段將session id送回服務器(服務器性能不好)。
------->統一資源定位符URL
<協議>://<主機>:<端口>/<路徑>,里面的字母不分大小寫
在百度輸入網址后,都發生了什么
(1)瀏覽器分析鏈接指向頁面的URL;
(2)瀏覽器向DNS請求解析www.baidu.com的IP
(3)域名系統解析出百度的IP是……
(4)瀏覽器與服務器建立TCP鏈接
(5)瀏覽器發出取文件命令
(6)服務器給出響應,將文件發送給瀏覽器
(7)釋放TCP鏈接
(8)瀏覽器顯示index.html中的所有文本
4、封裝與分用
(1)封裝
如上圖所示,展示的是上層協議通過封裝使用下層協議提供的服務,應用程序數據在發送到物理網絡之前,將沿著協議棧從上往下依次傳遞。每層協議都將在上層數據的基礎上加上自己的頭部信息,以實現該層的功能。
如上,經過數據鏈路層封裝的數據稱為幀,幀才是最終在物理網絡上傳送的字節序列。如下圖展示了以太網幀的封裝格式:
(2)分用
當幀到達目的主機時,將沿著協議棧自底向上依次傳遞。各層協議依次處理幀中本層負責的頭部數據,以獲取所需的信息,并最終將處理后的幀交給目標應用程序,這個過程稱為分用。分用是依靠頭部信息中的類型字段實現的。如上圖,展示了以太網幀的分用過程。
IP協議、ARP協議和RARP協議都使用幀傳輸數據,所以幀的頭部需要提供某個字段來區分它們,以以太網幀為例,它使用2字節的類型字段來標識上層協議;同樣,因為ICMP協議、TCP協議和UDP協議都使用IP協議,所以IP數據報的頭部采用16位的協議字段來區分它們;TCP報文段和UDP數據報則通過其頭部中的16位端口號字段來區分上層應用程序,我們可以通過在/etc/services文件中找到知名應用層協議使用的端口號,這里列舉幾個常用的端口號,DNS(53)、HTTP(80)。
幀通過上述分用步驟后,最終將封裝前的原始數據送至目標服務。
總的來說,在頂層目標服務看來,封裝和分用似乎沒有發生過。
5、TCP協議詳解
(1)面向連接、字節流、可靠傳輸
TCP連接是全雙工的,即雙方的數據讀寫可以通過一個連接進行。
TCP模塊發送出的TCP報文段的個數和應用程序執行的寫操作的次數之間沒有固定的數量關系。應用程序執行的讀操作的次數和TCP模塊接收到的TCP報文段的個數之間沒有固定的數量關系。綜上,發送端執行寫操作的次數和接收端執行的讀操作的次數之間沒有任何關系。這就是字節流的概念。
TCP采用發送應答機制和超時重傳機制,并且TCP協議會對接收到的TCP報文段(以IP數據報發送)重排、整理、再交付給應用層。
(2)TCP頭部結構
16位端口號:客戶端通常使用系統自動選擇的臨時端口號,而服務器則采用知名服務端口(/etc/services)。
32位序號:一次TCP通信過程中某一個傳輸方向上的字節流的每個字節的編號。
32位確認號:用作對另一方發送來的TCP報文段的響應,其值是收到的TCP報文段的序號值加一。
(3)TCP狀態轉移圖
三次握手,四次揮手:
客戶端通過connect系統調用主動與服務器建立連接,connect系統調用失敗的原因可能如下:
1)若connect連接的目標端口不存在,或者該端口仍被處于time_wait狀態的連接所占用,則服務器將給客戶端發送一個復位報文段,connect調用失敗;
2)若目標端口存在,但connect在超時時間內未收到服務器的確認報文段,則onnect調用失敗。
TIME_WAIT狀態存在的原因:
1)可靠的終止TCP連接;
2)保證讓遲來的TCP報文段有足夠的時間被識別并被丟棄。
TCP超時重傳:
為每個TCP報文段都維護一個重傳定時器,該定時器在TCP報文段第一次被發送時啟動,若超時時間內未收到對方的應答,TCP模塊將重傳TCP報文段,并重新設置定時器,
TCP擁塞控制:
為了提高網絡利用率,降低丟包率,并保證網絡資源對每條數據流的公平性。提出了擁塞控制。
擁塞控制的最終受控變量是發送端向網絡一次連續寫入(收到其中第一個數據的確認之前)的數據量,我們稱為SWND(發送窗口),SWND限定了發送端能連續發送的TCP報文段數量。這些TCP報文段的最大長度(僅指數據部分)稱為SMSS,發送端要合理選擇SWND的大小,若太小,則會引起明顯的網絡延遲;反之,若太大,則會導致網絡擁塞;接收方可通過其接收窗口(RWND)來控制發送端的SWND,但僅僅通過RWND是顯然不夠的,所以發送端引入了一個稱為擁塞窗口的狀態變量(CWND)。實際的SWND值是RWND和CWND中的較小者。
擁塞控制包括四個部分:慢啟動、擁塞避免、快速重傳、快速恢復
先來討論發送端未檢測到擁塞時所采用的積極擁塞避免方法:
TCP連接建立好之后,CWND被設置為初始值1W,大小為2——4個SMSS。此后,發送端每收到接收端的一個確認,其CWND就被設置為CWND+=min(N,SMSS),其中N是此次確認中包含的之前未被確認的字節數。慢啟動算法的理由是,TCP模塊剛開始發送數據時并不知道網絡的實際情況,需要一種試探的方式平滑地增加CWND的大小。
但是,如果不施加其他手段,慢啟動必然使得CWND很快膨脹,因此TCP擁塞控制中定義了另一個重要的狀態變量-----慢啟動門限(ssthresh),當CWND的大小超過了該值時,TCP擁塞控制將進入擁塞避免階段。擁塞避免算法使得CWND按照線性方式增長,主要有兩種實現方式:
1)每個RTT時間內按照式CWND+=min(N,SMSS)計算新的CWND,而不論該RTT時間內發送端收到多少個確認;
2)每收到一個對新數據的確認報文段,就按照CWND+=SMSSSMSS/CWND來更新CWND。
再來討論發送端檢測到擁塞發生(可能發生在慢啟動或者擁塞避免階段)時擁塞控制的行為:
發送端檢測擁塞發生的依據:
1)傳輸超時;
2)接收到重復的(3個)確認報文段;
對于第一種情況,依然采用慢啟動和擁塞避免,執行重傳并做調整:ssthresh=max(FlightSize/2,2SMSS) CWND<=SMSS,其中FlightSize是已經發送但未收到確認的字節數;對于第二種情況,則采用快速重傳和快速恢復(若第二種情況發生在重傳定時器溢出之后,則也當做第一種情況),當收到第3個重復的確認報文段時,按照ssthresh=max(FlightSize/2,2SMSS)計算ssthresh,按照式CWND=ssthresh+3SMSS計算CWND,并立即重傳丟失的報文段;每收到一個重復的確認,設置CWND=CWND+SMSS,此時發送端可以發送新的TCP報文段;當收到新數據的確認時,設置CWND=ssthresh;此時,擁塞控制將恢復到擁塞避免階段。
6、基本TCP套接口編程
Socket與TCP/IP的關系:
數據鏈路層、網絡層、傳輸層協議是在內核中實現的,因此操作系統實現了socket系統調用來使應用程序能夠訪問這些協議提供的服務。由socket定義的這一組API提供如下兩點功能:(1)將應用程序數據從用戶緩沖區中復制到TCP/UDP內核發送緩沖區,以交付內核來發送數據(send函數);(2)應用程序可以通過它們來修改內核中各層協議的某些頭部信息或其他數據結構,從而精細地控制底層通信的行為。
判斷大端or小端:
現代pc大多采用小端字節序,因此小端字節序又稱為主機字節序。大端字節序又稱為網絡字節序。
(1)socket函數
#include <sys/socket.h>
int socket(int family,int type,int protocal);
socket函數在成功時返回一個小的非負整數值,與文件描述符類似,稱為套接字。
(2)connect函數
TCP客戶用connect函數來建立一個與TCP服務器的連接。激發TCP的三次握手
#include <sys/socket.h>
int connect(int sockfd,const struct sockaddr *servaddr,socklen_t addrlen );
(3)bind函數
對于TCP調用bind函數可以指定一個端口號,指定一個IP地址。
(4)listen函數
(5)accept函數
由TCP服務器調用,從已完成連接隊列的頭部返回一個已完成連接。若已完成連接隊列為空,則進程睡眠。
exec函數系列