[TOC]
## 三次握手
* 第一次握手:建立連接時,客戶端發送syn包到服務器,并進入SYN_SENT狀態,等待服務器確認
* 服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
* 客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態 服務器收到確認報文段之后,也進入已建立連接狀態

## 四次揮手
* 客戶端應用進程發出連接釋放報文段,并停止再發送數據,進入 FIN-WAIT-1(終止等待1)狀態,等待服務器確認
* 服務器收到連接釋放報文段后即發出確認,進入 CLOSE-WAIT(關閉等待)狀態,服務器若發送數據,客戶端扔要接收
* 客戶端收到來自服務器的確認后,進入 FIN-WAIT-2(終止等待2)狀態,等待服務器發出連接釋放報文段
* 服務器沒有要發送的數據,發出連接釋放報文段,進入 LAST-ACK(最后確認)狀態,等待客戶端確認
* 客戶端收到連接釋放報文段后,發出確認,進入 TIME-WAIT(時間等待)狀態,經過時間等待計時器設置的時間 2MSL 后,進入 CLOSED(關閉) 狀態
* 服務器收到客戶端報文段后,進入 CLOSED 狀態

## 為什么TCP建立連接握手是3次,揮手需要4次?
因為當Server端收到Client端的SYN連接請求報文后,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能并不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四次揮手。
## 為什么 TCP 鏈接需要三次握手,兩次不可以么,為什么?
https://mp.weixin.qq.com/s/q-5Q0RiOAYaxNfvDtouMeQ
* 雙方才能確認自己與對方的發送與接收是正常的(單獨答比較片面)
* 三次握?才可以阻?重復歷史連接的初始化(最主要的原因)
如果是歷史連接(序列號過期或超時),則第三次握?發送的報?是 RST 報?,以此中?歷史連接;
如果不是歷史連接,則第三次發送的報?是 ACK 報?,通信雙?就會成功建?連接;
* 同步雙?的初始序列號
* 避免資源浪費
## TIME-WAIT 是什么,為什么必須等待 2MLS?
雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可以最后一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。在Client發送出最后的ACK回復,但該ACK可能丟失。Server如果沒有收到ACK,將不斷重復發送FIN片段。所以Client不能立即關閉,它必須確認Server接收到了該ACK。Client會在發送出ACK之后進入到TIME_WAIT狀態。Client會設置一個計時器,等待2MSL的時間。如果在該時間內再次收到FIN,那么Client會重發ACK并再次等待2MSL。所謂的2MSL是兩倍的MSL(Maximum Segment Lifetime)。MSL指一個片段在網絡中最大的存活時間,2MSL就是一個發送和一個回復所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那么Client推斷ACK已經被成功接收,則結束TCP連接。
> 精簡回答
1個 MSL 保證四次揮手中主動關閉方最后的 ACK 報文能最終到達對端
1個 MSL 保證對端沒有收到 ACK 那么進行重傳的 FIN 報文能夠到達
## 建立 TCP 連接為什么最后還要發送確認?
這主要是為了防止已失效的連接請求報文段突然又傳到了 TCP 服務器,避免產生錯誤。
## 如果已經建立了連接,但是客戶端突然出現故障了怎么辦?
TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求后都會重新復位這個計時器,時間通常是設置為2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以后每隔75秒鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認為客戶端出了故障,接著就關閉連接。
- 消息隊列
- 為什么要用消息隊列
- 各種消息隊列產品的對比
- 消息隊列的優缺點
- 如何保證消息隊列的高可用
- 如何保證消息不丟失
- 如何保證消息不會重復消費?如何保證消息的冪等性?
- 如何保證消息消費的順序性?
- 基于MQ的分布式事務實現
- Beanstalk
- PHP
- 函數
- 基礎
- 基礎函數題
- OOP思想及原則
- MVC生命周期
- PHP7.X新特性
- PHP8新特性
- PHP垃圾回收機制
- php-fpm相關
- 高級
- 設計模式
- 排序算法
- 正則
- OOP代碼基礎
- PHP運行原理
- zavl
- 網絡協議new
- 一面
- TCP和UDP
- 常見狀態碼和代表的意義以及解決方式
- 網絡分層和各層有啥協議
- TCP
- http
- 二面
- TCP2
- DNS
- Mysql
- 鎖
- 索引
- 事務
- 高可用?高并發?集群?
- 其他
- 主從復制
- 主從復制數據延遲
- SQL的語?分類
- mysqlQuestions
- Redis
- redis-question
- redis為什么那么快
- redis的優缺點
- redis的數據類型和使用場景
- redis的數據持久化
- 過期策略和淘汰機制
- 緩存穿透、緩存擊穿、緩存雪崩
- redis的事務
- redis的主從復制
- redis集群架構的理解
- redis的事件模型
- redis的數據類型、編碼、數據結構
- Redis連接時的connect與pconnect的區別是什么?
- redis的分布式鎖
- 緩存一致性問題
- redis變慢的原因
- 集群情況下,節點較少時數據分布不均勻怎么辦?
- redis 和 memcached 的區別?
- 基本算法
- MysqlNew
- 索引new
- 事務new
- 鎖new
- 日志new
- 主從復制new
- 樹結構
- mysql其他問題
- 刪除
- 主從配置
- 五種IO模型
- Kafka
- Nginx
- trait
- genergtor 生成器
- 如何實現手機掃碼登錄功能
- laravel框架的生命周期