目錄
一、TCP特性
二、報文格式
?TCP十大核心特性?
1. 確認應答
2. 超時重傳
3.?連接管理(三次握手,四次揮手)
三次握手
四次揮手
4. 滑動窗口
情況一:接收方的ACK丟失
情況二:發送方的數據包丟失
5. 流量控制
6. 擁塞控制
7. 延遲應答
8. 捎帶應答
9. 字節流粘包問題
?10. TCP的異常處理
面試題:如何使用UDP來實現可靠傳輸?
一、TCP特性
1.有連接
2.可靠傳輸
3.面向字節流
4.全雙工
二、報文格式
這是各大教科書上的
?這個和UDP一樣,是為了排版方便,容易給我們造成誤解,其實真正的結構是這樣的
?TCP十大核心特性?
1. 確認應答
發送方在發送一條數據給接收方之后,接收方會立刻返回一個ACK作為回應,表示自己收到該條數據
這就是確認應答,能夠保證傳輸的數據一定能發送給對方
2. 超時重傳
如果發送方沒有接收到回來的ACK相應,等待一段時間后,發送方默認該數據已經丟失,會重新發送該條數據給對方,如果依然沒有接收到ACK回應,那么會再次發送 ,但是每次發送的時間間隔會越變越長 , 這就是超時重傳
3.?連接管理(三次握手,四次揮手)
三次握手
- 發送方給接收方發送一條信息(發送SYN);
- 接收方接受到信息后,發送兩個消息,一個是確認應答(ACK),另一個是回復消息(SYN)
- 對于接收方發回來的ACK和SYN應答,發送方再次回復一個ACK確認應答
四次揮手
- ?發送方發送FIN,請求和接收方斷開連接
- 接收方回應ACK收到斷開請求
- 接收方向發起方也發送FIN,請求斷開連接
- ACK回應,接收方斷開連接請求
4. 滑動窗口
滑動窗口的出現時為了提高TCP傳輸效率的,我們沒有引入滑動窗口之前,TCP的大量時間都浪費在了等待ack上面,這時候我們便想到了一個辦法? 一次傳輸多個數據,
?而為了保證接受方能夠承擔同時處理的最大數據,保證接受方不崩潰,我們限制了發送方的最大發送?
也就是說,滑動窗口能夠保證,接收方最大同時處理數據的上限,和發送方最大能發送數據的上限
如果在這種批量傳輸的情況下,出現數據丟失怎么辦?
情況一:接收方的ACK丟失
這里可以看到,我們的ACK即使丟了,也無妨,下一條ACK只要能到達,ACK就不需要重新傳送,因為發送5001的意思是前5000個數據全部收到了
??情況二:發送方的數據包丟失
這里可以看到,即使是數據包丟失了也無所謂,主機2會持續的返回1001,這樣主機1就會重新發送一次1001 ,??所以滑動窗口,是很好的一種提高TCP傳輸速率的方法
5. 流量控制
接收端處理數據的速度是有限的。如果發送端發的太快,導致接收端的緩沖區被打滿,這個時候如果發送端繼續發送,就會造成丟包,繼而引起丟包重傳等等一系列連鎖反應。
因此TCP支持根據接收端的處理能力,來決定發送端的發送速度。這個機制就叫做流量控制
- 接收端將自己可以接收的緩沖區大小放入 TCP 首部中的 "窗口大小" 字段,通過ACK端通知發送端;
- 窗口大小字段越大,說明網絡的吞吐量越高;
- 接收端一旦發現自己的緩沖區快滿了,就會將窗口大小設置成一個更小的值通知給發送端;
- 發送端接受到這個窗口之后,就會減慢自己的發送速度;
- 如果接收端緩沖區滿了,就會將窗口置為0;這時發送方不再發送數據,但是需要定期發送一個窗口探測數據段,使接收端把窗口大小告訴發送端
6. 擁塞控制
?簡單來說,就是速度如果達到了傳輸的上限,那么就會立刻反彈回一個較低的值,然后繼續增長速率
如此反復,直到穩定在了一個比較合理的數值范圍內,這就是擁塞控制
最開始我們的速率增長是指數級別的增長,比如? 2的一次方?-> 2的二次方 -> 2的三次方....
然后到了一個比較高的值之后,為了防止下一個次方直接超出接受范圍很多
所以從那個值之后,我們采用線性增長,而不是指數增長了
7. 延遲應答
接收方接受數據之后,不會立刻相應給發送方,而是等待一段時間,等接收方接收到多組數據后再返回
8. 捎帶應答
?如果在很短的時間內,接收方收到很多信息,并且都需要返回,那么多條返回消息,就可以合并為一條消息返回
9. 字節流粘包問題
當TCP發送多條數據,數據都存儲再緩沖區中,由于我們的數據是字節流的,所以我們的數據很有可能會粘到一起,無法區分出哪些是一條數據
粘包問題處理方法:
1.通過分隔符:比如指定一個分隔符作為包的結束標記,這樣每一個包就區分開來了
2.通過指定報的長度:比如再報文開頭位置聲明長度,這樣讀數據的時候,只讀取指定長度的數據,就不會發生粘包問題了
10. TCP的異常處理
情況一:程序突然崩潰
操作系統會自動回收程序遺留/占用的資源,類似于close操作,然后發生四次揮手情況二:程序正常退出
同情況一,回收資源+四次揮手情況三:沒法發送和接收數據(電腦壞了,網絡斷了)
接收方無法接受
接收方無法接受數據,也就是無法回應ACK相應給發送方,當發送方多次發送數據也沒有ACK回應之后,就默認接收方不行了,然后停止發送數據發送方無法發送
在接收方和發送方里面存在一個"心跳包",雙方會周期性發送一個小數據,判斷對方是否存活,如果檢測到發送方沒有心跳回應,那么就默認發送方沒了,接收方也就停止接收數據.注意:在接收方電腦壞了的情況下也能用心跳包判斷,但是ACK更加直接
面試題:如何使用UDP來實現可靠傳輸?
其實是考察TCP,我們只需要基于UDP在應用層,實現確認應答,超時重傳,引入序列號等待操作就可以了