傳輸層
負責端與端之間的數據傳輸。也就是說進程與進程之間的數據傳輸,進程用端口來表示,所以也可以叫做端口和端口之間的傳輸。
端口號
端口號爲0-65535,一般0-1023爲知名端口,不推薦使用,在一臺主機上表示一個進程。
操作系統拿到網卡接收的數據之後,通過數據中的端口號知道數據放到哪一個socket緩衝區中
五元組
一條數據中包含的五個信息。源IP+源端口+目的IP+目的端口+協議
主機上網絡狀態的查看:netstat -anptu
傳輸層的傳輸協議
UDP協議
UDP協議的定義:無連接,不可靠,面向數據報
面向數據報:數據整條收發;靈活性低;但是不會造成粘包問題。每條數據有長度標識,數據有明顯的間隔,帶有報頭的整條發,整條收,傳輸不靈活,但不存在粘包問題。
UDP不提供可靠性: 它把應用程序傳給IP層(網絡層)的數據發送出去,但是並不保證它們能到達目的地。UDP數據報封裝成一份IP數據報的格式如圖所示:
IP首部20字節,UDP首部8字節
UDP協議包含字段
UDP的協議字段包括源端口,目的端口,UDP長度,UDP校驗和(總共8字節,統稱爲UDP首部)
源端口/目的端口
負責傳輸,爲了確定數據應該哪個進程處理
校驗和
通過二進制的反碼求和,它也等價於二進制求和在取反
計算UDP校驗和方法計算16位的二進制和,包括UDP首部數據。將校驗和首先置爲0,將每個16位的按位相加,第17,18位如果出現進位的話,將結果重新與結果的第1,2位相加,再將所得的結果取反碼,最後得到的結果即爲UDP校驗和,存在校驗和字段中。
數據報長度
UDP提供整條數據嚮應用層交付,實際上收到的數據都是經過檢驗過的,比如發送”ABCD“,不會出現“ABED”,只可能發生亂序或者丟包。因此如果發送成功但是是亂序的情況,那麼用戶需要在應用層進行包序管理。
UDP包的大小可以達到64K,但實際上以太網數據幀的長度必須在46~1500字節,這是由以太網的物理特性決定的。這個1500被稱爲鏈路層的MTU(最大傳輸單元)
如果直接發一個超過MTU的包,就會在協議層分片,這樣的問題是如果一個分片在傳輸中出錯了即校驗不正確(這是較容易發生的),整個傳輸的UDP包可能就丟失了。
又因爲UDP數據報的首部8字節,所以UDP數據報的數據區最大長度爲64-8K。如果發送給予的數據大於64K-8則會報錯;
UDP在傳輸層並不會進行分片,在IP層纔會進行分片操作。
UDP的緩衝區
UDP沒有真正意義上的緩衝區。調用sendto會直接交給內核,由內核數據傳給網絡層協議進行後續傳輸動作。
UDP具有接收緩衝區,但是這個接收緩衝區不能保證收到的UDP報的順序和發送的UDP報的順序一樣。如果緩衝區滿了,則再到達的UDP數據則會被丟棄。
TCP協議
TCP傳輸是面向連接,可靠傳輸,面向字節流
源端口/目的端口
一個IP地址和端口的組合稱爲“套接字”和端點,在IP協議中的源IP地址和目的地址和TCP協議中的源端口和目的端口,組成了“一對”套接字(發送端的套接字和接收端的套接字)
序列號
每一個TCP報文段中的第一個字節都會被賦予一個序列號。序列號是個32位數,到達2^32-1後會再回到0
確認序列號
也稱ACK或ACK字段。確認號包含的值爲”確認號的發送方“希望對方接收的下一個序列號。即序列號+數據長度。
4位TCP報頭長度
表示TCP頭部有多少個32位bit(有多少個4字節),由於"選項字段”大小是可變的,所以“頭部長度”是必須的,TCP頭部長度最大爲60字節,如果沒有選項字段,那麼TCP頭部長度爲20字節。
6位標誌位
URG: 緊急指針是否有效
ACK: 確認號是否有效
PSH: 提示接收端應用程序立刻從TCP緩衝區把數據讀走
RST: 對方要求重新建立連接; 我們把攜帶RST標識的稱爲復位報文段
SYN: 請求建立連接; 我們把攜帶SYN標識的稱爲同步報文段
FIN: 通知對方, 本端要關閉了, 我們稱攜帶FIN標識的爲結束報文段
窗口大小
在TCP協議中,一個分組從發送端發送到接收端中,接收端應該返回一個ACK號。
每一個分組都是從“序列號”開始的,我們定一個術語“窗口”,來表示:已發送的分組們,但這些分組還未返回確認號(ACK號)。窗口中的分組數量稱之爲:“窗口大小”,不會大於緩衝區的大小
下圖爲發送方的窗口以及其他分組隊列:
如果發送方下一步接收到了序列號爲4的分組“ACK”,則“窗口向右滑動一個分組”,意味着分組4可以釋放了,分組7可以發送了。這種行爲稱之爲:“窗口滑動協議”(下面詳細敘述)
TCP校驗和
該校驗算法與IP、ICMP、UDP校驗算法一致,其覆蓋了TCP頭部和數據中的一些字段。
緊急指針
只有在有URG字段時纔有效。該指針是一個加到“序列號字段”上的正偏移,以產生“緊急數據”的最後一個字節的序列號。
面向連接
這就不得不在提到TCP的三次握手和四次揮手了。以客戶端先發送請求爲例。
三次握手
首先客戶端先發送一個SYN包,請求建立連接。此時客戶端處於SYN_SEND狀態。這時服務端接收到了請求,會先發送一個SYN+ACK組合包確認一下是否建立連接。此時服務端處於SYN_RECV狀態。當客戶端接收到了組合包時,明白了服務端同意建立請求,這時客戶端再次發送一個ACK包,’'表達"想要建立連接的決心,進行回覆確認。當服務端再次收到這個ACK包之後,雙方都處於ESTABLISH狀態,此時雙方可以互相發送數據信息了。
四次揮手
發送了一段數據之後,客戶端想要斷開連接。客戶端向服務端發送一個FIN包,請求斷開連接,此時客戶端處於FIN_WAIT_1狀態,等待ACK回覆。服務端接收到了之後,向客戶端發送一個ACK包,同意斷開連接。此時服務端處於CLOSE_WAIT狀態,客戶端處於FIN_WAIT_2狀態。這時服務端會在發送一個FIN包確認一下,是否斷開連接,最後確認一次,此時服務端處於LAST_ACK狀態。客戶端收到該FIN包之後,會立刻回覆一個ACK確認包,此時客戶端處於TIME_WAIT狀態,但是客戶端會等待2個MSL(最大報文段生成時間),因爲可能最後一次ACK包如果丟失的話,服務端會在發送一個FIN包過來。當在這個等待的時間內,服務端沒有在發送之後,徹底斷開連接,服務端和客戶端都進入CLOSED狀態。等待回收資源。
可靠傳輸
確認應答機制或者超時重傳機制是保證安全到達
協議字段中的序號/確認序號是進行包序管理
校驗和爲了驗證數據的一致性
因爲TCP爲了保證可靠傳輸,因此犧牲了部分傳輸性能;爲了保證TCP傳輸性能不會進一步下降(因爲ack丟失而重傳),因此又有了一些新的機制。
滑動窗口機制+擁塞控制+快速重傳機制
滑動窗口:
窗口是接收方爲了告訴發送方最多發送多少,而不是非要讓發送方發送多少。
通信雙方通過協議中的窗口字段,來協商能夠一次發送的最多數據,然後連續發送多條數據;在socket當中使用兩個指針維護窗口後沿(起始位置)和前沿(發送的結束位置)。
發送端:若窗口中後沿數據沒有接收到ack確認,後沿就不能向前移動,數據就不能從緩衝區移除,接收到ack確認後窗口,前後沿向後移動。
接收端:當接收數據的時候,如果沒有接收到第一條數據,則後沿不能移動,只有接收到數據之後,後沿纔會向前移動。
滑動窗口機制規定:
ack確認丟失的情況:每條數據都要進行回覆,並且應該按序逐條回覆,如果沒有收到第一條,但是都到了第二條,第二條就不能先回復,應該先回復第一條;帶來的好處就是,因爲第一條ack丟失後,如果發送端收到第二條的回覆,也會認爲第一條正常接收;第一條就不需要重傳了。
數據丟失的情況:當數據連續發送n條,但是第一條數據丟失,接收端先接收到第二條,這時候接收端認爲第一條數據有可能丟失,因此直接開始向發送端發送第一條數據的重傳請求;連續發送三次(防止網絡延遲又接收到數據報);當發送端連接收到三條重傳請求,則會對這條數據進行重傳。
延遲應答機制
接收方接收數據後不立刻進行確認回覆,而是等待一段時間,因爲這段延遲的時間內,有可能用戶recv將緩衝區中的數據取走,窗口就儘可能地保證最大窗口,保證傳輸地吞吐量。儘可能地保證滑動窗口地性能。
捎帶應答機制
接收方對每一條數據地確認回覆都需要發送一個TCP數據報;但是空報頭地傳輸會降低性能
因此會考慮在即將要發送地數據報中包含有確認信息(可以少發一個確認的空報頭)
面向字節流:傳輸字節流
發送方:每次調用send都會將數據放到緩衝區中,然後內核選擇合適時機發送數據。
接收方:網卡接收到數據,都會將數據放到接收緩衝區中,用戶recv就是從接收緩衝區中取數據
粘包問題主要發生位置
發送緩衝區中的數據堆積 or 接收緩衝區中的數據堆積
粘包本質原因:數據之間沒有明顯邊界,tcp只管傳輸數據的字節流導致發送端/接收端因爲數據的堆積在實際發送或recv時一次獲取到半條或多條數據,這就是TCP的粘包問題
如何解決TCP粘包
TCP在傳輸層沒有數據邊界,但是用戶可以在應用層進行邊界處理。
**常見方法:**特殊字符間隔(比如HTTP協議);定長數據(UDP頭中包含長度)
對於定長的包,保證每次都按固定大小讀取即可;
對於變長的包,可以在包頭的位置,約定一個包總長度的字段,從而就知道了包的結束位置;
對於變長的包,還可以在包和包之間使用明確的分隔符(應用層協議,是程序員自己來定的只要保證分隔符和正文不衝突即可);
TCP小結
爲了保證TCP的可靠性,同時又儘可能地提高性能。
可靠性:校驗和;序列號;確認應答;超時重發;連接管理;
提高性能:擁塞控制;流量控制;滑動窗口;超時重傳;快速重傳;延遲應答;捎帶應帶
TCP和UDP的比較
TCP和UDP之間並不能絕對的說誰比較好,而是通過場景來判斷
TCP用於可靠傳輸,應用於文件傳輸,重要狀態更新場景
UDP用於高速傳輸和實時性要求比較高的通信領域,比如視頻傳輸。UDP還可以用於廣播