活動發起人@小虛竹 想對你說:
這是一個以寫作博客為目的的創作活動,旨在鼓勵大學生博主們挖掘自己的創作潛能,展現自己的寫作才華。如果你是一位熱愛寫作的、想要展現自己創作才華的小伙伴,那么,快來參加吧!我們一起發掘寫作的魅力,書寫出屬于我們的故事。我們誠摯邀請你參加為期14天的創作挑戰賽!
提醒:在發布作品前,請將不需要的內容刪除。
1.應用層
我們之前編寫完了基本的 java socket ,要知道,我們之前所寫的所有代碼都在應?層,都是為了 完成某項業務,如翻譯等。關于應?層,我們在講解完畢基本的 TCP/IP 協議之后,我們會單獨來進 ?講解。
2.傳輸層
負責數據能夠從發送到傳輸到接收端。
2.1 再談端口號
端口號標識了一個主機上進行通信的不同的應用程序。
在TCP/IP協議中,?"源IP","源端?號","?的IP","?的端?號","協議號"這樣?個五元組來標識?個 通信(可以通過netstat-n查看);
端?號范圍劃分
? 0-1023:知名端?號,HTTP,FTP,SSH等這些?為使?的應?層協議,他們的端?號都是固定的.
? 1024-65535:操作系統動態分配的端?號.客?端程序的端?號,就是由操作系統從這個范圍分配 的.
2.2UDP協議
UDP協議格式
? 16位UDP?度,表?整個數據報(UDP?部+UDP數據)的最??度;?如果校驗和出錯,就會直接丟棄;
UDP的特點:
- 無連接:知道對端的IP和端?號就直接進?傳輸,不需要建?連接,
- 不可靠傳輸:沒有確認機制,沒有重傳機制;如果因為?絡故障該段?法發到對?,UDP協議層也不會給應 ?層返回任何錯誤信息;(如何理解這里的不可靠,?向數據報?應?層交給UDP多?的報?,UDP原樣發送,既不會拆分,也不會合并;)
- 面向數據報:不能夠靈活的控制讀寫數據的次數和數量
- 全雙工
我們接下來了解UDP報頭,我們所熟知的HTTP協議的報頭是文本格式的,UDP/TCP/IP的報頭是二進制格式的。
長度
整個UDP數據報長度(報頭+載荷),長度屬性也是兩個字節,表示范圍0~65535(64KB).
端口號
一個端口號的取值范圍是0~65535,實際上一般把1024以下的端口保留,我們寫代碼都用1024~65535這個范圍的。服務器的端口是程序員指定的(提前指定好,客戶端才能訪問到),客戶端的端口是系統自動分配的空閑端口(如果提前指定了,可能會與你客戶端上的程序起沖突)。
校驗和
驗證數據是否發生修改,之前我們將HTTP的數字簽名是為了防止黑客篡改(防人),但UDP的校驗和不是為了防人,和安全性無關,而是為了防止出現運輸過程中的“比特翻轉”(即1變0,0變1)。
發送之前,先計算一個校驗和,把整個數據包的數據都代入,把數據與校驗和一起發送給對端,接收方收到之后重新計算一下校驗和,和收到的校驗和進行對比(UDP發現校驗和不一致,就會直接丟棄)。UDP的校驗和使用了CRC方式來進行校驗(循環冗余校驗),把每個字節(除了校驗和位置的部分之外),都當做整數,進行累加,溢出來也沒有關系,繼續加最終得到結果,crc校驗和傳輸到對端,數據出現錯誤了,對端再次 計算的校驗和就會和第一個校驗和不以樣。
認為兩個原始數據相同,使用相同的校驗和算法,得到的校驗和也應該是相同的,反之,兩個校驗和相同,原始數據一定也相同(可能存在變數)。
UDP使?注意事項
UDP總長度最大是64KB,可以表述為UDP總長度達到64KB或UDP攜帶的載荷長度達到64KB上限。
我們注意到,UDP協議?部中有?個16位的最??度.也就是說?個UDP能傳輸的數據最??度是 64K(包含UDP?部). 然?64K在當今的互聯?環境下,是?個?常?的數字.如果我們需要傳輸的數據超過64K,就需要在應?層?動的分包,多次發送,并在接收端?動拼裝。
2.3TCP協議
TCP協議特點:有鏈接,面向字節流,可靠傳輸,全雙工。
TCP協議段格式
1.16位源端口號/16位目的端口號:傳輸層的核心內容;
2.4位首部長度:表?該TCP頭部有多少個32位bit(有多少個4字節);所以TCP頭部最??度是15*?4=60。
3.選項:選項的存在,導致tcp報頭長度是可變的。
4.保留6位:TCP報頭中就預留了一些“保留位”,現在先不用,但是先占個位子。
5.:TCP最核心的6個標志位
- ?URG:緊急指針是否有效.
- ?ACK:確認號是否有效,ack為1,表示是應答報文.
- ?PSH:提?接收端應?程序?刻從TCP緩沖區把數據讀?.
- ?RST:對?要求重新建?連接;我們把攜帶RST標識的稱為復位報?段.
- SYN:請求建?連接;我們把攜帶SYN標識的稱為同步報?段.
- ?FIN:通知對?,本端要關閉了,我們稱攜帶FIN標識的為結束報?段.
6.16位校驗和:用來校驗數據是否出現錯誤.
7.針對確認應答中的情況,給數據進行編號,其中確認序號只在應答報文中才生效。
8.16位緊急指針:標識哪部分數據是緊急數據
TCP的核心機制
可靠性:此處的可靠性,不是說A給B發一個消息,B100%能收到,而是A給B發了消息之后,盡量讓B收到消息。
TCP核心機制一:確認應答
保證可靠性的一個關鍵前提,發送方知道自己的數據是否被對方收到,需要對方給返回一個“應答報文”(acknowledge.ack),發送方知道應答報文,就可以確認對方收到了。
舉個例子,我們用短信給別人發送多條消息時,正常情況下,如圖所示
但是在網絡上會出現后發先至的情況,如圖所示,這種情況會引起誤解,
那么針對這種情況,我們又該如何解決,接下來我們介紹一下TCP的解決方案
TCP將每個字節的數據都進行了編號,即為序列號。上述列子編號如上圖所示:
每?個ACK都帶有對應的確認序列號,意思是告訴發送者,我已經收到了哪些數據;下?次你從哪?開始 發.
1.TCP是面向字節流的,在編號時,不是按照用條、2條來編號的,而是按照“字節”的方式來編號的,每個字節都分配一個編號,編號是連續遞增的。
? ? ? ? 一個TCP的載荷是由多個字節構成的,需要多個編號,那么此處的序號該怎么填寫:序號字段填寫載荷部分的第一個字節的序號,序號連續遞增;確認序號填法是把收到的載荷數據的最后一個字節序號+1。
2.引入序號之后,接收方就可以根據序號對數據進行排序,TCP需要先處理后發先至的情況,確保應用程序通過socket api讀到的數據順序(即確保代碼里讀到的數據和發送方寫入的數據順序一致)是正確的。
3.TCP報頭不參與排序,序號、確認序號都是針對載荷的,TCP在接收方這里會安排“接收緩沖區”,(內存,操作系統內核里),通過網卡讀到的數據,先放到緩沖區中,后續代碼里調用read,也是從接收緩沖區來讀的。
4.在接收緩 沖中,根據序號來排序,序號小的在前面,大的在后面,確保前面的數據已經到了,然后read才能接觸阻塞,如果是后面的數據先到,read會繼續阻塞,不會讀取到數據。
TCP核心機制二:超時重傳
1.超時重傳是針對丟包的情況做出處理,這里首先會設置一個超時時間,
比如A給B發送數據等B的回應,如果達到等待時間上限,還沒有收到ack,A就認為傳輸過程中發生丟包情況。這里的丟包可能是A給B發生的數據丟了或者B給A返回的ack丟了。
2.為什么會發生丟包現象?
因為網絡結構是非常復雜的,數據報經過某個路由器,交換機轉發的時候,該路由器、交換機已經非常繁忙了,導致當前所需要轉發的數據量超出路由器、交換機的轉發能力上限,此時,數據報會消耗更多的時間,才能到達對方,跟糟糕的是,數據報太多,路由器、交換機根本處理不過來,接收緩沖區已滿,只能丟棄。
3.丟包是不能避免的客觀現象,而重傳是有效對抗丟包的手段。
4.如何判斷是否丟包?
引入超時時間來判斷是否丟包,TCP中,判斷超時時間的閾值,不是固定數值,是動態改變的。
假設當前A向B發送數據,丟包時間的閾值是T,當A給B傳輸發生超時之后,就會延長這個時間閾值,即延長這個時間,但不是無休止的,超時次數達到一定程度或等待時間達到一定程度,就會認為網絡出現嚴重故障,放棄這一次傳輸。
5.針對A給B發生的數據丟了或者B給A返回的ack丟了這兩種情況,發送方A區分不了當前是那種情況,所有都重傳。
情況1
A給B發生的數據丟了,直接重傳就可以了。
情況2
對于這種情況,B已經收到了一份數據,如果重傳,B就會收到兩份一樣的數據,如果tcp不處理,可能會使應用層讀到兩次一樣的數據,所以tcp會在內部進行去重操作,此時根據序號,在接收緩沖區中尋找,如果存在,就直接丟棄;如果不存在,才放進去。
注:確認應當和超時重傳是TCP最核心的兩個機制,保證了TCP能夠進行可靠運輸。