### 建立TCP連接的過程
> 三次握手建立TCP連接
- 第一次握手:客戶端向服務器發送1個連接請求的報文段。
- 第二次握手:服務器收到請求連接報文段后,若同意建立鏈接,則向客戶端發送連接確認的報文段。
- 第三次握手:客戶端收到確認報文后,向服務器再次發出連接確認報文段。
- 成功進程TCP的三次握手后,就建立了一條TCP連接,即可傳送應用層的數據了。

> 為什么TCP建立連接時需要三次握手
- 結論:防止服務器端因接收了已經失效的鏈接請求報文,從而一直等待客戶端請求。最終導致形成死鎖,浪費資源。
- 解決方法:建立鏈接時采用三次握手,即關鍵的是第三次握手。客戶端不會向服務端的確認報文再次發送確認。服務器由于收不到客戶端的確認信息,即知道客戶端并無要求建立TCP連接。故服務器不會一直等待客戶端發送數據,即不會形成死鎖狀態。

> SYN 洪泛攻擊
> - 服務端TCP資源分配時刻是在完成第二次握手的時候。而客戶端TCP資源分配時刻是在完成第一次握手的時候。
> - 這就是的服務器容易收到SYN洪泛攻擊,即同時多個客戶端發送連接請求,從而需要進行多個請求的TCP連接的資源分配。
### 釋放TCP連接的過程
> 在通信結束后,雙方都可以釋放連接,共需四次揮手。
- 客戶端向服務端發送一個連接釋放的報文。
- 服務器收到連接釋放的報文后,則向客戶端發回連接釋放的確認報文。
- 若服務器已無要向客戶端發送數據,則發出釋放連接的報文。
- 客戶端收到連接釋放報文后,則向服務器發回連接釋放確認的報文段。


> 為什么TCP釋放連接需四次揮手
- 結了:為了雙方都能通知對方需釋放,斷開連接。

> 為什么客戶端關閉連接前需要等待2MSL時間?
- 原因:為了保證客戶端發送的最后1個連接釋放確認報文能到達服務器,從而是的服務器能正常釋放連接。

### 數據傳輸過程
應用層發送數據是把數據放到了操作系統的TCP發送緩存中。操作系統發送時,去TCP發送緩存中取數據組成TCP數據包。接收端接收解析后,把字節流按順序放入TCP接收緩存,每次從緩存中取一定的字節數據交個應用層。
### 如何實現TCP可靠傳輸
* **自動重傳協議(ARQ)**
發送端發送一個數據之后,等待接收端響應成功接收的確認后,再發送下一個數據包(停止等協議)
一定時間內沒有收到確認,發送端重傳這個數據包(超時重傳),最大等待時間略大于往返時延。所以重傳是自動進行的。
如果接收端發送的確認丟失,或者確認遲到即確認沒有在最大等待時間內到達發送端,這兩種情況也都會導致發送端進行超時重傳。這種情況下,接收端會丟棄重復的數據。所以TCP協議還支持**去重**的功能
通俗來說,ARQ協議就是,**只要你沒在一定時間內告訴我收到了,我就認為你沒收到。**
停止等待協議實現簡單,但是信道利用率低。因為發送數據的時間要遠小于等待的時間。
* **流水線傳輸**
上面提到的ARQ傳輸協議的信道利用率非常低,已經被淘汰。目前TCP協議中采用流水線傳輸。即發送端發送一個數據包后,不等待接收端的ACK就立即發送下一個準備好的數據包。當一個包發送了時間x之后,還沒收到收到這個包的ACK,就會重傳這個包。x的取值略大于網絡的往返時延TTL。假設在時間x內,可以發送n個數據包,那么發送端必須要緩存n個還沒有收到ack的數據包。即發送端維護一個發送窗口。

發送窗口內是發送了還沒有收到ACK的數據包,當發送窗口內有數據收到ACK之后,就可以被移出窗口,并且窗口左邊沿向前推進。當窗口內的數據大于窗口的最大長度時,就不能繼續發送數據了,需要等待ACK或者進行重傳。
舉個例子,上圖中假如滑動窗口的大小是5,此時窗口已經被占滿。有兩種情況,如果收到了數據包1的ACK那么數據包1被溢出窗口,窗口向前推進繼續發送第6個包。如果沒收到ACK,會重傳數據包1,其實窗口也會向前推進,次數數據包6的內容跟數據包1的內容相同,即數據包1的重傳。
**累計確認**是對上述機制的進一步優化,即接收端如果收到了連續的數據包1、2、3,只需要在ACK里回復收到了3,發送端就可以隱式的知道1、2、3都發送成功了。