前言面試
這一篇我將介紹的是你們面試常常被會問到的,三次握手四次揮手的過程。之前我聽到這個是什麼意思呀?聽的我一臉蒙逼,可是學習以後就原來就那麼回事!算法
這一層的功能也挺簡單的,運輸層提供應用層提供端到端通訊服務,通俗的講,兩個主機通信,也就是應用層上的進程之間的通訊,也就是轉換爲進程和進程之間的通訊了,咱們以前學到網絡層,windows
IP協議能將分組準確的發送到目的主機,可是停留在網絡層,並不知道要怎麼交給咱們的主機應用進程,經過前面的學習,咱們學習有mac地址,經過mac地址能找到同一個網絡下主機,有IP地址,緩存
經過ip地址能找到不一樣網絡下的網絡,結合mac地址就能找到對應主機,那麼怎麼找到主機應用進程呢,確定也有一個東西來標識它,那就是咱們常說的端口了。服務器
端口,佔有16位,其大小也就有65536個,是從0~65535.也就是一臺計算機有65535個端口,主機之間的通信,也就是應用進程之間的通信,都要依靠端口,一個進程對應一個端口,網絡
進程A和進程B通訊,進程A分到的端口爲60000,進程B分到的端口爲60001,進程A經過端口60000發送數據給進程B,就知道要交給60001端口,也就到了進程B中 ,這樣就達到了通訊的目的。併發
1)熟知端口:0-1023, 也就是一些固定的端口號,好比http使用的80端口,意思就是在訪問網址時,咱們訪問服務器的端口就是80,而後服務器那邊傳網頁的數據給咱們。tcp
2)登記端口:1024-49151,好比微軟開發了一個系統應用,該應用在通信或使用時,須要使用到xxx端口,那麼就要去登記一下這個端口,以避免有別人公司的應用使用同一個端口號,函數
例如,windows系統中的3389端口,就是用來實現遠程鏈接的,就固定了這臺計算機若是要使用遠程鏈接服務,就打開3389端口,別人就能使用遠程鏈接連你了,默認是不打開的。
3)客戶端端口:49152-65535,通常咱們使用某個軟件,好比QQ,等其餘服務,隨機拿這個範圍內的端口,而不是去拿前面哪些固定的,拿到等通信結束後,就會釋放該端口。
知道了端口是什麼?運輸層具體作了什麼事情呢?運輸層就是將兩個端口連起來通訊的介質,否則光知道兩個端口有什麼用,怎麼通訊的,仍是要靠運輸層來作這個事情,其中重要的就是靠兩個協議,UDP和TCP協議。
UDP:User Datagram Protocol 用戶數據報協議
無鏈接、不可靠
無鏈接:意思就是在通信以前不須要創建鏈接,直接傳輸數據。
不可靠:是將數據報的分組從一臺主機發送到另外一臺主機,但並不保證數據報可以到達另外一端,任何須須的可靠性都由應用程序提供。在 UDP 狀況下,雖然能夠確保發送消息的大小,
卻不能保證消息必定會達到目的端。沒有超時和重傳功能,當 UDP 數據封裝到 IP 數據報傳輸時,若是丟失,會發送一個 ICMP 差錯報文給源主機。即便出現網絡阻塞狀況,
UDP 也沒法進行流量控制。此外,傳輸途中即便出現丟包,UDP 也不負責重發,甚至當出現包的到達順序雜亂也沒有糾正的功能。
UDP在IP報文中的位置如圖所示:
UDP報文格式如圖所示:
1)UDP首部
源端口號:佔16位,源主機的應用進程所使用的端口號
目標端口號:佔16位,目標主機的應用進程所使用的端口號,也就是咱們須要通訊的目標進程
UDP(包)報長度:UDP用戶數據報的長度,數據部分+UDP首部之和爲UDP報長度。
檢驗和:檢驗和是爲了提供可靠的 UDP 首部和數據而設計,這裏不要和上面的不可靠傳輸搞混淆了,這裏提供可靠的UDP首部,是由於一個進程可能接受多個進程過來的報文,那麼如何區分他們呢,
就是經過5個東西來進行區分的, 「源 IP 地址」、「目的 IP 地址」、「協議號」、「源端口號」、「目標端口號」的,這個檢測可靠,是檢測接受哪一個正確的報文,也就是說是哪一個報文要進這個端口。那個不可靠,
說的是這個報文可能丟失,可能其中數據損壞了咱們不關心,可是這些的前提是,你得傳輸到正確的目的地去,否則亂出亂髮數據報,豈不是亂套了。
2)UDP僞首部
就是拿到IP層的一些數據,由於要進行檢驗和,就必需要有這些數據。其中檢驗的算法跟IP層中檢驗首部的辦法是同樣的。
分析:
一個目標進程中,其中的報文,目標端口,目標ip地址確定都是同樣的,可是源IP地址和源端口就可能不同,這就說明了不一樣源而同一目的地的報文會定位到同一隊列。
這跟接下來咱們要討論的TCP不同,由於UDP是無鏈接的,你們都是用這一條通道,因此其隊列中就會出現上面所說的這樣的狀況。
在選擇使用協議的時候,選擇UDP必需要謹慎。在網絡質量使人十分不滿意的環境下,UDP協議數據包丟失會比較嚴重。可是因爲UDP的特性:它不屬於鏈接型協議,於是具備資源消耗小,
處理速度快的優勢,因此一般音頻、視頻和普通數據在傳送時使用UDP較多,由於它們即便偶爾丟失一兩個數據包,也不會對接收結果產生太大影響。好比咱們聊天用的ICQ和QQ就是使用的UDP協議。
1)應用層協議中DNS,也就是根據域名解析ip地址的一個協議,他使用的就是UDP
2)DHCP,這個是給各電腦分配ip地址的協議,其中用的也是UDP協議
3)IGMP,咱們說的多播,也就是使用的UDP,在多媒體教師,老師拿筆記本講課,咱們在下面經過各自的電腦看到老師的畫面,這就是經過UDP傳輸數據,因此會出現有的同窗卡,
有的同窗很流暢,就是由於其不可靠傳輸,可是卡一下,對接下來的觀看並無什麼映像。
百度上說:
TCP協議是面向鏈接的、可靠傳輸、有流量控制,擁塞控制,面向字節流傳輸等不少優勢的協議。其最終功能和UDP同樣,在端和端之間進行通訊,可是和UDP的區別仍是很大的。
1)當應用層向TCP層發送用於網間傳輸的、用8位字節表示的數據流,TCP則把數據流分割成適當長度的報文段,最大傳輸段大小(MSS)一般受該計算機鏈接的網絡的數據鏈路層的最大傳送單元(MTU)限制。
以後TCP把數據包傳給IP層,由它來經過網絡將包傳送給接收端實體的TCP層。
2)TCP爲了保證報文傳輸的可靠,就給每一個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。而後接收端實體對已成功收到的字節發回一個相應的確認(ACK);
若是發送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的數據(假設丟失了)將會被重傳。
在數據正確性與合法性上,TCP用一個校驗和函數來檢驗數據是否有錯誤,在發送和接收時都要計算校驗和;同時可使用md5認證對數據進行加密。
在保證可靠性上,採用超時重傳和捎帶確認機制。
在流量控制上,採用滑動窗口[1] 協議,協議中規定,對於窗口內未經確認的分組須要重傳。
3)在擁塞控制上,採用廣受好評的TCP擁塞控制算法(也稱AIMD算法)。該算法主要包括三個主要部分:1)加性增、乘性減;2)慢啓動;3)對超時事件作出反應。
1)源端口號
2)目標端口號
3)序列號:由於在TCP是面向字節流的,他會將報文都分紅一個個字節,給每一個字節進行序號編寫,好比一個報文有900個字節組成,那麼就會編成1-900個序號,而後分幾部分來進行傳輸,
好比第一次傳,序列號就是1,傳了50個字節, 那麼第二次傳,序列號就爲51,因此序列號就是傳輸的數據的第一個字節相對全部的字節的位置。
4)確認應答:如剛說的例子,第一次傳了50個字節給對方,對方也會迴應你,其中帶有確認應答,就是告訴你下一次要傳第51個字節來了,因此這個確認應答就是告訴對方要傳第多少個字節了
5)首部長度:就是首部的長度,
6)保留:給之後有須要在用,這個保留的位置放的東西是跟控制位相似的
7)控制位:目前有的控制位爲6個
URG:緊急,當URG爲1時,表名緊急指針字段有效,標識該報文是一個緊急報文,傳送到目標主機後,不用排隊,應該讓該報文儘可能往下排,讓其早點讓應用程序給接受。
ACK:確認,當ACK爲1時,確認序號纔有效。當ACK爲0時, 確認序號沒用
PSH:推送,當爲1時,當遇到此報文時,會減小數據向上交付,原本想應用進程交付數據是要等到必定的緩存大小才發送的,可是遇到它,就不用在等足夠多的數據才向上交付,
而是讓應用進程早點拿到此報文,這個要和緊急分清楚,緊急是插隊,可是提交緩存大小的數據不變,這個推送就要排隊,可是遇到他的時候,會減小交付的緩存數據,提早交付。
RST:復位,報文遇到很嚴重的差錯時,好比TCP鏈接出錯等,會將RST置爲1,而後釋放鏈接,所有從新來過。
SYN:同步,在進行鏈接的時候,也就是三次握手時用獲得,下面會具體講到,配合ACK一塊兒使用
FIN:終止,在釋放鏈接時,也就是四次揮手時用的。
8)窗口:指發送報文段一方的接受窗口大小,用來控制對方發送的數據量(從確認號開始,容許對方發送的數據量)。也就是後面須要講的滑動窗口的窗口大小
9)檢驗和:檢驗首部和數據這兩部分,和UDP同樣,須要拿到僞首部中的數據來幫助檢測
10)選項:長度可變,介紹一種選項,最大報文段長度,MSS。 可以告訴對方TCP,個人緩存能接受報文段的數據字段的最大長度是MSS個字節。若是沒有使用選項,那麼首部固定是20個字節。
11)填充:就是爲了讓其成爲整數個字節
面向鏈接(三次握手):在通訊以前,會先經過三次握手的機制來確認兩端口之間的鏈接是否可用。而UDP不須要確認是否可用,直接傳。
三次握手機制:
一開始客戶端和服務端都是關閉狀態,可是在某個時刻,客戶端須要和服務端進行通訊,此時雙方都會各自準備好端口,服務器段的端口會處於監聽狀態,等待客戶端的鏈接。
客戶端可會知道本身的端口號,和目的進程的端口號,這樣才能發起請求。
第一次握手:客戶端想與服務器進行鏈接了,因此狀態變爲主動打開,同時發送一個鏈接請求報文給服務器段SYN=1,而且會攜帶x個字節過去。
發送完請求鏈接報文後,客戶端的狀態就變爲了SYN_SENT,能夠說這個狀態是等待發送確認(爲了發送第三次握手時的確認包)
第二次握手:服務端接收到鏈接請求報文後,從LSTTEN狀態變爲被動打開狀態,而後給客戶端返回一個報文。這個報文有兩層意思,一是確認報文,而能夠達到告訴客戶端,我也打開鏈接了。
發完後,變爲SYN_RCVD狀態(也能夠說是等待接受確認狀態,接受客戶端發過來的確認包)
第三次握手:客戶端獲得服務器端的確認和知道服務器端也已經準備好了鏈接後,還會發一個確認報文到服務器端,告訴服務器端,我接到了你發送的報文,接下來就讓咱們兩個進行鏈接了。
客戶端發送完確認報文後,進入ESTABLISHED,而服務器接到了,也變爲ESTABLISHED。
正常狀況下,通訊一方請求創建鏈接,另外一方響應該請求,可是若是出現,通訊雙方同時請求創建鏈接時,則鏈接創建過程並非三次握手過程,並且這種狀況的鏈接也只有一條,並不會創建兩條鏈接。
同時打開鏈接時,兩邊幾乎同時發送 SYN,並進入 SYN_SENT 狀態,當每一端收到 SYN 時,狀態變爲 SYN_RCVD,同時雙方都再發 SYN 和 ACK 做爲對收到的 SYN 進行確認應答。
當雙方都收到 SYN 及相應的 ACK 時,狀態變爲 ESTABLISHED
經過1)數據編號和積累確認 2)以字節爲單位的滑動窗口 3)超時重傳時間 4)快速重傳 這四個方面來達到可靠傳輸的目的。
1)、數據編號:將每一個字節進行編號,有900個字節,就從1到900進行編號
積累確認:服務器端不是接收到一個字節就發一個確認,那樣效率過低,而是當接收到4,5個時,在發送一個確認,那麼在以前的確認以前的數據就算髮送成功了的。
2)滑動窗口:這個跟在數據鏈路層講個滑動窗口同樣。每次能發送的數據是在此窗口中的,接到了多少數據,就日後滑多少數據
3)超時重傳時間:這個也在鏈路層講過,若是等待一段時間後,還沒接收到確認報文,那麼就從新傳
4)快速重傳:在滑動窗口中的應用,好比傳了1234 6到服務器端,老辦法是在4以後的全部數據度要從新傳,而這個快速重傳就只須要等待傳了5這個序號,就能夠繼續往下接收數據了。
在傳輸層中,有接受緩存和發送緩存這兩個東西的存在,因此每次發送數據過去另外一端時,都會把這些數據給帶過去,讓對方知道本身的這兩個緩存的大小,而後來合理的設置本身的發送窗口的大小,
若是對方的緩存快滿了,對方在傳送數據過來的時候,就會告訴本身,少發一點數據過來,本身就設置滑動窗口小一點,讓對方有緩衝的機會,而不會致使緩存溢出,不讓本身的報文被丟棄。
其實跟流量控制差很少,可是站的角度更大,此時既考慮了對方接收不過來,緩存太多溢出致使,又考慮在線路中,線路上的傳輸速率就那麼大,可是有不少人同時用,發送的數據太多,就會使線路發現擁塞,
也就是路由器可能轉發不過來,致使大量數據丟失,這兩個問題。因此擁塞控制這個解決方案,大概意思就是當檢測到有網絡擁塞時,就會讓本身的滑動窗口變小,但具體是怎麼變化的,就是根據算法來算了,
發送窗口的上限值 = Min[rwnd,cwnd]
rwnd:接受窗口,根據接受緩存,而定的接受窗口,接收緩存還有不少,那麼接收窗口就大
cwnd:擁塞窗口,根據線路中的擁塞情況來決定,線路中不擁塞,那麼此窗口就大,
發送窗口是取兩個中較小值。這個仍是能夠理解的。
慢啓動算法、快速恢復算法、結合來達到對擁塞進行控制的。
通訊完成後,鏈接就會被釋放,經過四次揮手機制來完成這個事情。
第一次揮手:從ESTABLISHED變爲主動關閉狀態,客戶端主動發送釋放鏈接請求給服務器端,FIN=1。發送完以後就變爲FIN_WAIT_1狀態,這個狀態能夠說是等待確認狀態。
第二次揮手:服務器接收到客戶端發來的釋放鏈接請求後,狀態變爲CLOSE_WAIT,而後發送確認報文給客戶端,告訴他我接收到了你的請求。爲何變爲CLOSE_WAIT,緣由是是客戶端發送的釋放鏈接請求,
可能本身這端還有數據沒有發送完呢,因此這個時候整個TCP鏈接的狀態就變爲了半關閉狀態。服務器端還能發送數據,而且客戶端也能接收數據,可是客戶端不能在發送數據了,只可以發送確認報文。
客戶端接到服務器的確認報文後,就進入了FIN_WAIT_2狀態。也能夠說這是等待服務器釋放鏈接狀態。
第三次揮手:服務器端全部的數據度發送完了,認爲能夠關閉鏈接了,狀態變爲被動關閉,因此向客戶端發送釋放鏈接報文,發完以後本身變爲LAST_WAIT狀態,也就是等待客戶端確認狀態
第四次揮手:客戶端接到釋放鏈接報文後,發送一個確認報文,而後本身變爲TIME_WAIT,而不是立馬關閉,由於客戶端發送的確認報文可能會丟失,丟失的話服務器就會重傳一個FIN,也就是釋放鏈接報文,
這個時候客戶端必須還沒關閉。 當服務器接受到確認報文後,服務器就進入CLOSE狀態,也就是關閉了。可是因爲上面說的這個緣由,客戶端必須等待必定的時間纔可以進入CLOSE狀態。
正常狀況下,通訊一方請求鏈接關閉,另外一方響應鏈接關閉請求,而且被動關閉鏈接。可是若出現同時關閉鏈接請求時,通訊雙方均從 ESTABLISHED 狀態轉換爲 FIN_WAIT_1 狀態。
任意一方收到對方發來的 FIN 報文段後,其狀態均由 FIN_WAIT_1轉變到 CLOSING 狀態,併發送最後的 ACK 數據段。當收到最後的 ACK 數據段後,狀態轉變化 TIME_WAIT,
在等待 2MSL 時間後進入到 CLOSED 狀態,最終釋放整個 TCP 傳輸鏈接。其過程入下:
總結:通常須要保證數據可靠時,都會使用tcp協議:http協議進行網站的訪問時,使用的就是tcp。