TCP的原理,作為一個應用開發者來說,可能在平常開發中,99%時間用不上。因為平常用得網路框架比如OkHttp等都已經幫我們封裝好,我們不需要知道里面的原理直接用介面即可,很簡單。
但是作為一個優秀的開發者,我們必須要知其然也需要知其所以然。而且特別在面試的時候, TCP握手和揮手原理經常被問到,如果答得上來,容易加分....
閒話少說,直接上原理圖
具體流程:
1:使用者端(Client)嘗試請求連線,會隨機產生一個數Sequence碼 X,發給伺服器端(Server)
2:伺服器端拿到了使用者端發過來的 Sequence碼 X ,會 將 X + 1 生成 ACK碼,然後自己也會隨機產生一個數Sequence碼Y
然後把ACK 和 Y 一同打包發給 使用者端
3:使用者端拿到使用者端反饋的 ACK 和 Sequence碼,先驗證 ACK 是否在 X 加了1,是就代表伺服器端反饋的就是自己之前的請求。
然後再把 Sequence碼Y 加 1,生成ACK碼,把 ACK碼返回給伺服器端。
(同理伺服器端也會驗證 返回的ACK碼是否在Sequence碼Y基礎上加了1 )
至此,握手通訊成功,可以傳遞資料...
因為要保證連線的有效性,避免資源浪費。試想使用者端發了連線請求給伺服器端,由於網路擁擠等異常原因,請求遲遲傳送不到伺服器端,這時使用者端收不到反饋資料,早下線掉線了。過了幾個小時伺服器端才收到請求,如果這時不握手驗證,直接就把資料返回過去,這就造成資源的浪費。如果在資料傳遞前驗證握手通訊,即可保證雙方都「線上」,也可以保證 請求-返回 是一一對應的。
具體流程:
1:使用者端嘗試斷開連線,會傳送斷開TCP連線請求的報文,會將FIN置1,並會隨機產生 Sequence碼 M,發給我 伺服器端
2:伺服器端收到 TCP連線請求報文,會將M+1 生成 ACK碼,返回給使用者端,使用者端接收到自己的 Sequence碼 加了1,說明斷開 請求已經得到驗證。
3:伺服器端在收到斷開TCP連線請求的報文,並不會立馬斷開連線,而是等自己的資料全部都傳送出去才會斷開連線。所以伺服器端在保證已經把所有資料傳送出去之後,把FIN置1,產生隨機產生Sequence碼N,把N傳送給使用者端。
4:使用者端收到伺服器端的請求斷開報文,會把 N+1 生成ACK,反饋給伺服器端。伺服器端校驗到ACK是在Sequence碼N加了1,從而完成伺服器端請求的驗證回覆。
至此,4次揮手完成。
因為 TCP連線是全雙工的,一方需要斷開,得另一方確認,這樣一來一回就是四次通訊了。再者這麼設計,也是為了保證資料傳輸的完整性。因為C傳送了斷開報文,僅僅代表C沒有了資料傳遞過來,C還能接受資料。如果S接收到斷開報文就立馬斷開,假如此時還有剩餘資料沒有傳輸完呢?這樣直接斷開就會造成資料傳遞丟失了。所以伺服器端會先同意使用者端的斷開請求,再確保伺服器端自己已經把全部資料傳送完,再傳送斷開報文給使用者端。所以步驟2和3一般是分開來傳送的。所以這樣一來一回的揮手,就是4次揮手了。
可以!只要伺服器端在收到斷開報文時,已經確保了所有資料已經傳送完了。這樣步驟2和3可以合在一起傳送。這樣就是三次揮手了。不過,一般會分開來傳送的。