為了使全球范圍內不同的計算機廠(chǎng)家能夠相互之間能夠比較協(xié)調的進(jìn)行通信,這個(gè)時(shí)候就有必要建立一種全球范圍內的通用協(xié)議,以規范各個(gè)廠(chǎng)家之間的通信接口,這就是網(wǎng)絡(luò )七層模型的由來(lái)。本文首先會(huì )對網(wǎng)絡(luò )七層模型的功能進(jìn)行介紹,然后會(huì )講解傳輸層的兩個(gè)重要協(xié)議:TCP和UDP協(xié)議,并且會(huì )著(zhù)重講解TCP協(xié)議中的三次握手和四次揮手的過(guò)程。
1. 網(wǎng)絡(luò )七層模型
關(guān)于網(wǎng)絡(luò )七層模型,我們首先以一個(gè)圖例來(lái)展示其功能:
- 應用層:主要指的是應用程序部分,比如我們的Java程序,應用層所產(chǎn)生的數據成為應用層數據,典型的應用層協(xié)議,比如有HTTP協(xié)議,dubbo的rpc協(xié)議,這些都是由我們的應用層程序自己定義的;
- 表示層:這一層主要是對應用層的數據進(jìn)行一些格式轉換,加解密或者進(jìn)行壓縮和解壓縮的功能;
- 會(huì )話(huà)層:會(huì )話(huà)層的主要作用是負責進(jìn)程與進(jìn)程之間會(huì )話(huà)的建立、管理以及終止的服務(wù);
- 傳輸層:傳輸層提供了兩臺機器之間端口到端口的一個(gè)數據傳輸服務(wù),因為應用層、表示層和會(huì )話(huà)層所針對的都是某個(gè)應用進(jìn)程,而進(jìn)程是和端口綁定的,但是同一臺服務(wù)器上是可以有多個(gè)進(jìn)程的,因而傳輸層提供的就是這種不同的端口到端口的訪(fǎng)問(wèn),以實(shí)現區分不同進(jìn)程之間的通信服務(wù)。在傳輸層最典型的協(xié)議有TCP和UDP協(xié)議,TCP提供的是面向連接的、可靠的數據傳輸服務(wù),而UDP則是無(wú)連接的、不可靠的數據傳輸服務(wù)。在上面的圖中我們也可以看出,經(jīng)過(guò)傳輸層之后,數據會(huì )被加上TCP或者UDP頭部,用以實(shí)現不同傳輸層協(xié)議的功能;
- 網(wǎng)絡(luò )層:傳輸層提供的是同一臺主機上的端口到端口的傳輸服務(wù),而網(wǎng)絡(luò )層則提供的是不同主機之間的連接服務(wù),最典型的網(wǎng)絡(luò )層協(xié)議就是IP協(xié)議,網(wǎng)絡(luò )層會(huì )將當前的數據包加上一個(gè)IP頭部,從而實(shí)現目標機器的尋址;
- 數據鏈路層:這一層是承接軟件和硬件的一層,由于其會(huì )將當前的數據報發(fā)送到不穩定的物理層硬件上進(jìn)行傳輸,因而為了保障數據的完整性和可靠性,數據鏈路層就提供了校驗、確認和反饋等機制,用以提供可靠的數據報傳輸服務(wù);
- 物理層:物理層的主要作用就是將0101這種二進(jìn)制的比特流數據轉換為光信號,用以在物理介質(zhì)上進(jìn)行傳輸。
網(wǎng)絡(luò )七層模型主要是提供的一種規范,而在這每一層上為了實(shí)現不同的功能,各個(gè)計算機廠(chǎng)商都會(huì )實(shí)現自己的協(xié)議,這些協(xié)議的標識就是通過(guò)一些協(xié)議頭和進(jìn)行的,比如上面圖中,數據在經(jīng)過(guò)每一層的封裝之后都會(huì )為其加上自己的協(xié)議頭部,當數據經(jīng)過(guò)物理介質(zhì)傳輸到目標機器上后,其就會(huì )反過(guò)來(lái),將數據進(jìn)行一層一層的解析,解析的過(guò)程其實(shí)就是根據其每一層頭部信息來(lái)實(shí)現該層的相關(guān)功能。
另外,網(wǎng)絡(luò )七層模型是一種比較理想化的模型,現在應用比較廣泛的是網(wǎng)絡(luò )五層模型,五層模型與七層模型的主要區別在于將應用層、表示層和會(huì )話(huà)層統一劃分到應用層中了,由應用程序實(shí)現其相關(guān)的功能。
2. TCP與UDP
在我們的應用開(kāi)發(fā)過(guò)程中,我們其實(shí)不需要太過(guò)于關(guān)注底層相關(guān)的功能,這些只需要相關(guān)的服務(wù)提供商提供相應的功能即可。不過(guò)在傳輸層之中,我們需要特別關(guān)注一下現在廣泛使用的兩個(gè)協(xié)議:TCP和UDP協(xié)議。這兩個(gè)協(xié)議之間的主要區別如下:
TCPUDP面向連接無(wú)連接提供數據可靠保證不提供數據可靠性保證速度相對較慢速度較快占用資源較多占用資源較少
關(guān)于TCP和UDP,可以看到,這兩個(gè)協(xié)議各自分別有非常鮮明的特點(diǎn):TCP雖然占用資源較多,速度相對較慢,但是提供了可靠的數據傳輸服務(wù),這在大多數的互聯(lián)網(wǎng)業(yè)務(wù)中是非常必要的;而UDP雖然不提供可靠性的數據保證,但是其速度非???,而且占用資源較小,這在一些對數據可靠性較低的場(chǎng)景中是非常有用的,比如音視頻服務(wù),物聯(lián)網(wǎng)數據上報服務(wù)等等,這些情況下,數據丟失一兩幀都是可以接受的。
TCP和UDP在資源占用上的區別,不僅體現在數據傳輸方式上,還體現在了數據的傳輸格式上。對于數據傳輸方式,TCP每次發(fā)送數據的方式都是按照時(shí)間窗口的方式一個(gè)數據報一個(gè)數據報的發(fā)送,并且需要等待每個(gè)數據報都給數據發(fā)送方響應ACK,這個(gè)時(shí)候才會(huì )發(fā)送下一個(gè)數據窗口的數據,如果當前窗口內有任意一個(gè)數據報沒(méi)有發(fā)送成功,那么整個(gè)窗口內的數據都會(huì )重新發(fā)送;而UDP則沒(méi)有窗口的概念和對應的ACK機制,其獲取到每一個(gè)數據報之后,都只是簡(jiǎn)單的為其封裝UDP協(xié)議頭,然后將其發(fā)送出去,其不會(huì )管這個(gè)數據是否發(fā)送成功,因而UDP傳輸比TCP是要快很多的。對于數據傳輸格式,這里我們以TCP和UDP的數據報的格式進(jìn)行講解,如下是TCP的數據報格式:
可以看到,TCP數據報的頭部中不僅包含了源端口號和目的端口號,還包含了序號、確認序號、首部長(cháng)度、標志位等等信息,總的來(lái)看,除去真正的數據部分,頭部信息占用的字節數就達到了192字節,當然,這么多字段主要的作用是為了實(shí)現TCP面向連接的可靠性傳輸的功能。如下則是UDP數據報的格式:
可以看到,這里UDP的數據包格式相對于TCP就非常的精簡(jiǎn)了,其頭部主要就只有源端口號、目的端口號、長(cháng)度和校驗和字段,這些總共占用的字節數是8個(gè)字節。這也就是UDP協(xié)議傳輸速率非??斓牧硪粋€(gè)原因。
2. 三次握手和四次揮手
TCP是一個(gè)提供可靠傳輸服務(wù)、面向連接的的傳輸層協(xié)議,其可靠性保證主要是通過(guò)每次數據報發(fā)送時(shí)的ACK機制實(shí)現的,而其連接的建立和釋放則主要是通過(guò)三次握手和四次揮手的方式實(shí)現的。如下是其三次握手和四次揮手的過(guò)程:
對于三次握手,其整體過(guò)程如下:
- 首先客戶(hù)端會(huì )發(fā)送一個(gè)建立連接的請求,其標志位中會(huì )帶上SYN=1, seq=x,這里的SYN=1根據前面TCP頭部信息的講解中我們知道,其表示建立連接的請求,而seq=x則只是當前請求的一個(gè)序號,不同的請求是有不同的序號的,加這個(gè)序號的原因也是為了將其與服務(wù)端的響應請求關(guān)聯(lián)起來(lái);
- 在服務(wù)端接收到客戶(hù)端建立連接的請求之后,其就會(huì )返回SYN=1, ACK=1, seq=y, ack_seq=x+1,這里的SYN=1, ACK=1表示的是對客戶(hù)端建立連接的請求的同意響應,seq=y則標識了這是服務(wù)端的一次數據發(fā)送,而ack_seq=x+1則表示其是對客戶(hù)端的seq=x的請求的一個(gè)響應;
- 在客戶(hù)端接收到服務(wù)端的響應的時(shí)候,客戶(hù)端就能夠確認服務(wù)端是能夠正常接收和發(fā)送數據的,而服務(wù)端在接收到客戶(hù)端的第一次請求的時(shí)候也能夠確認客戶(hù)端能夠正常的發(fā)送請求。這個(gè)時(shí)候,客戶(hù)端就會(huì )發(fā)送一個(gè)ACK=1, seq=x+1, ack_seq=y+1給服務(wù)器,服務(wù)器接收到后就會(huì )完成連接的建立。
可以看到,前兩次請求都是建立連接所必要的,而客戶(hù)端要發(fā)送第三次請求的原因主要有兩點(diǎn):
- 可以讓服務(wù)器確??蛻?hù)端是能夠正常發(fā)送和接收請求的;
- 由于連接的建立是在不穩定的網(wǎng)絡(luò )上進(jìn)行的,因而這里有可能第一次請求是由于客戶(hù)端在某個(gè)時(shí)間點(diǎn)發(fā)送的,但是由于網(wǎng)絡(luò )延遲,導致很久之后服務(wù)器才接收到該請求,但此時(shí)服務(wù)器并不知道這個(gè)連接建立的請求是否是正常請求,其還是會(huì )正常發(fā)送一個(gè)同意建立連接的響應給客戶(hù)端,如果第一請求是由于網(wǎng)絡(luò )延遲造成的,那么客戶(hù)端是不會(huì )再發(fā)送第三次握手給服務(wù)器的,這個(gè)時(shí)候服務(wù)器等待超時(shí)后也就不會(huì )建立這一次的連接了。
對于四次揮手,其是在客戶(hù)端與服務(wù)器交互完成之后,由客戶(hù)端發(fā)起的。四次揮手的主要流程如下:
- 客戶(hù)端首先會(huì )發(fā)送一個(gè)FIN=1, seq=u給服務(wù)器,根據前面TCP頭部信息的講解,我們知道FIN=1表示這是一個(gè)斷開(kāi)連接的請求,而seq=u則標識了這次請求的一個(gè)序號;
- 服務(wù)器接收到客戶(hù)端的斷開(kāi)連接的請求后,其就會(huì )向客戶(hù)端發(fā)送一個(gè)ACK=1, seq=v, ack_seq=u+1的響應,這里的seq=v還是表示當前請求的序號,而ack_seq=u+1則表示這是對客戶(hù)端發(fā)送的seq=u的斷開(kāi)連接的請求的響應,但是需要注意的是,這個(gè)請求并不表示服務(wù)器同意斷開(kāi)連接,此時(shí)還只是一個(gè)半關(guān)閉的狀態(tài),因為此時(shí)服務(wù)器可能還有數據在進(jìn)行處理沒(méi)有發(fā)送給客戶(hù)端,此時(shí)服務(wù)器就會(huì )完成這些斷開(kāi)連接的工作;
- 待服務(wù)器完成了斷開(kāi)連接的準備工作之后,其就會(huì )給客戶(hù)端發(fā)送一個(gè)FIN=1, ACK=1, seq=w, ack_seq=u+1的響應,注意,這個(gè)過(guò)程中客戶(hù)端一直都處于等待狀態(tài)的。這里相對于前一次響應,多了一個(gè)FIN=1,就是表示當前是確認斷開(kāi)連接的請求;
- 客戶(hù)端在接收到服務(wù)器的響應之后,其就會(huì )給服務(wù)器發(fā)送一個(gè)ACK=1, seq=u+1, ack_seq=w+1的響應,表示同意斷開(kāi)連接,服務(wù)器接收到后就會(huì )斷開(kāi)連接,而客戶(hù)端則會(huì )等待一小段時(shí)間后自行斷開(kāi)連接。
3. 小結
本文首先講解了OSI網(wǎng)絡(luò )七層模型,詳細講解了模型中每一層的作用,然后講解了傳輸層中TCP和UDP的主要區別,從傳輸方式和傳輸數據格式上對兩種協(xié)議進(jìn)行了對比,最后講解了TCP協(xié)議中三次握手和四次揮手的主要過(guò)程,并且詳細講解了每一步的作用。