以前覺得了解這些底層東西並沒有什麼實質性的用戶,但是很多面試都會問到相關的。也不知道爲什麼。
直到在工作中遇到了一些問題,涉及到了這些底層的知識。
現在重新整理一下,以備後面需要時查詢。
我們知道,在tcp的c/s模型中,需要有一個server來監聽一個端口,然後client去連接這個端口。
這在編程上面的體現就是:
server首先調用socket創建一個套接字,
然後調用bind函數去綁定一個端口,
然後調用listen去監聽(listen會設置一個等待連接隊列的最大連接個數,當等待的用戶超過這個個數時,會直接拒絕)。
最後調用accept去接收連接的用戶,accept會返回一個資源描述符。
client方也是首先調用socket創建一個套接字,
然後connect去連接服務器。
三次握手就是在client調用connect時發生的。客戶端調用connect會首先發送一個SYN分節,它會告訴服務器客戶將在連接中發送的數據的初始序列號(關於這個序列號,詳情請查找tcp協議的一些詳細內容)。服務端收到這個SYN時,會返回一個ASK,同時發送一個自己的SYN,客戶端收到服務端的SYN時,在發送一個ASK。如下圖所示:
這就是經典的三次握手 。因爲總共發送了三次數據,所以說三次握手。
SYN和ASK是tcp協議的兩個標誌位。下圖:tcp協議包頭。
tcp用三個連節創建一個連接,終結一個連接則需要四個分節。
首先我們稱主動調用close函數的一方爲主動關閉端,另一方爲被動關閉端。
主動關閉端發送一個FIN分節,被動關閉端收到這個分節,發送一個ASK應答。
一段時間後,被動關閉方接受到文件結束符的應用程序也會調用close來關閉這個套接字,同時也會發送一個FIN分節。
主動關閉方接受到FIN時,會發送一個ASK應答。
中間涉及四個分節,所以也叫四次握手。如下圖:
上述的是主動斷開連接的情況,如果不主動斷開連接,那麼連接是一直保留着的。即使沒有任何數據交換。所以tcp服務端都會有一個心跳掉線機制。具體實現是在程序上層實現的。服務端檢查到多久客戶端沒有發送數據包或者心跳包,就主動斷開連接。