TCP報文格式
面試
- 序號:seq序號,佔32位,標識從TCP源端向目的端發送的字節流,發起方發送數據時對此標記
- 確認號:ack,佔32位,只有ACK標誌位爲1時,確認序號字段纔有效,ack=seq+1
- 標誌位有6個
- URG:緊急指針有效
- ACK:確認序號有效
- PSH:接收方應該儘快將這個報文交給應用程序,爲後續數據騰出空間
- RST:重置鏈接
- SYN:發起一個新鏈接
- FIN:釋放一個鏈接
TCP三次握手
![](http://static.javashuo.com/static/loading.gif)
三次握手過程
三次握手由客戶端觸發
- 第一次握手:首先客戶端將標誌位SYN設爲1,隨機產生一個值seq=x,並將該數據包發送給服務器,客戶端計入SYN_SENT狀態,等待服務器確認。
- 第二次握手:服務器收到數據包有標誌位SYN=1,知道是客戶端請求創建鏈接,服務器此時將SYN和ACK都設爲1,ack=J+1,隨機產生一個seq=K,
而且將該數據包發送給客戶端以確認鏈接請求,此時服務器進入SYN_RCVD狀態。
- 第三次握手:客戶端收到確認後,檢查ACK是否爲1,ack是否爲J+1,若是正確則將標誌位ACK置爲1,ack=K+1,並將數據包發送給服務器,
服務器檢查ack是否爲K+1,ACK是否爲1,若是正確則雙方數據通訊成功,此時客戶端和服務端都進入ESTABLISHED狀態。
TCP四次揮手
四次揮手能夠由客戶端或服務器來觸發
四次揮手過程
![](http://static.javashuo.com/static/loading.gif)
- 第一次揮手:客戶端發送一個FIN,用來關閉客戶端與服務器的數據傳送,此時客戶端進去FIN_WAIT_1狀態
- 第二次揮手:服務器收到FIN後,發送一個ACK給客戶端,而且確認序號爲收到序號+1(一個FIN佔用一個序號),此時服務器進入CLOSE_WAIT狀態
- 第三次揮手:服務器發送一個FIN,用來關閉服務器到客戶端的數據傳送,此時服務器進到LAST_ACK狀態
- 第四次揮手:客戶端收到FIN後,進入TIME_WAIT狀態,向服務器發送一個ACK,確認序號爲收到序號+1,此時服務器進入CLOSED狀態,四次揮手結束
常見面試題
爲何創建鏈接是三次握手,揮手確要四次呢?
服務器在LISTEN狀態下,收到創建鏈接請求的SYN報文後,把ACK和SYN放在一個報文裏發送給客戶端。關閉鏈接時,當收到對方的FIN報文時,僅僅表示對方再也不發送數據了可是還能接收數據,
己方也不必定把所有數據發送給對方。因此己方能夠當即CLOSE,也能夠發送一些數據給後,再發送FIN報文給對方來表示贊成關閉鏈接。己方ACK和FIN通常分開發送服務器