TCP的特點(diǎn)及目的
TCP是一種面向有連接的協(xié)議,只有在確認(rèn)通信對(duì)端存在時(shí)才會(huì)發(fā)送數(shù)據(jù)。它充分的實(shí)現(xiàn)了數(shù)據(jù)傳輸時(shí)各種控制功能,TCP通過校驗(yàn)和、序列號(hào)、確認(rèn)應(yīng)答、重發(fā)控制、連接管理以及窗口控制實(shí)現(xiàn)可靠性傳輸,是可靠傳輸。
TCP可靠傳輸?shù)募夹g(shù)
- 利用窗口滑動(dòng)技術(shù)提高速度
發(fā)送端的窗口大小由接收端的窗口大小決定。發(fā)送端窗口接收到數(shù)據(jù)向發(fā)送端發(fā)送確認(rèn)數(shù)據(jù)包,窗口移動(dòng),清理緩沖區(qū)。若發(fā)生數(shù)據(jù)丟失,會(huì)重發(fā)請求數(shù)據(jù)包并在可選字段設(shè)置SACK(選擇性確認(rèn)),注明缺失的那一部分,目的就是不用將丟失后的所有部分重新發(fā)送。
- 流量控制
發(fā)送端主機(jī)根據(jù)接收端主機(jī)的窗口大小通知進(jìn)行流量控制
- 擁塞控制
最初將發(fā)送端的窗口設(shè)置為1。每收到一個(gè)確認(rèn)應(yīng)答,窗口的值會(huì)增加1個(gè)段。
- 連接管理
三次握手和四次揮手
三次握手和四次揮手是面試中的重要考點(diǎn),這里會(huì)對(duì)這兩個(gè)過程進(jìn)行詳細(xì)的分析
三次握手
三次握手的過程
剛開始客戶端處于Closed的狀態(tài),服務(wù)端處于Listen狀態(tài)。
- 第一次握手:客戶端給服務(wù)器發(fā)送一個(gè)SYN報(bào)文,并指明客戶端的初始化序列號(hào)seq = x。此時(shí)客戶端處于SYN_Send狀態(tài)。
- 第二次握手:服務(wù)器收到客戶端的SYN報(bào)后,會(huì)以自己的SYN報(bào)作為應(yīng)答,并且指定自己的初始化序列號(hào)seq = y。同時(shí)會(huì)把客戶端的序列號(hào)值+1作為確認(rèn)號(hào)ack的值,即ack = x+1,表示自己已經(jīng)收到了客戶端的SYN,此時(shí)服務(wù)器處于SYN_REVD的狀態(tài)。
- 第三次握手:客戶端收到SYN報(bào)文后,會(huì)發(fā)送一個(gè)ACK報(bào)文,把服務(wù)器的序列號(hào)值+1作為確認(rèn)號(hào)的值,即ack = y+1,表示已經(jīng)收到了SYN報(bào)文。并以x+1作為自己的序列號(hào)值,此時(shí)客戶端處于established狀態(tài)。
- 服務(wù)器收到ACK報(bào)文后,也處于established狀態(tài),此時(shí),雙方已建立起了聯(lián)系。
三次握手的作用
- 確認(rèn)雙方的接收能力、發(fā)送能力是否正常。
- 指定自己的初始化序列號(hào),為后面的可靠傳送做準(zhǔn)備。
- 如果是HTTPS協(xié)議的話,三次握手這個(gè)過程,還會(huì)進(jìn)行數(shù)字證書的驗(yàn)證以及加密秘鑰的生成。
為什么要采用三次握手,兩次不行么?
有一種情況是A發(fā)出的第一個(gè)連接請求報(bào)文段并沒有丟失,而是在某些網(wǎng)絡(luò)結(jié)點(diǎn)長時(shí)間滯留了,以致延誤到連接釋放后的某個(gè)時(shí)間才能到達(dá)B。本來這是個(gè)早已失效的報(bào)文段,但B收到此失效的連接請求報(bào)文段后,就誤以為A又重新發(fā)出了一次新的連接請求。于是又向A發(fā)送確認(rèn)報(bào)文段,同意建立連接。若不采用三次握手,只要B發(fā)出確認(rèn)報(bào)文,新的連接就建立了。由于現(xiàn)在A并沒有發(fā)出建立連接的請求,因此不會(huì)理睬B的確認(rèn),也不會(huì)向B發(fā)送數(shù)據(jù)。
三次握手圖解
四次揮手
四次揮手的過程描述
剛開始雙方都處于established狀態(tài),如果客戶端先發(fā)起關(guān)閉請求,則:
- 第一次揮手:客戶端發(fā)送一個(gè)FIN報(bào)文,報(bào)文中會(huì)指定一個(gè)序列號(hào)seq = x。此時(shí)客戶端處于FIN_WAIT1狀態(tài)。
- 第二次揮手:服務(wù)端收到FIN之后,會(huì)發(fā)送ACK報(bào)文,且把客戶端的序列號(hào)值+1作為ACK報(bào)文的應(yīng)答號(hào)值,表明已經(jīng)收到客戶端的報(bào)文了,此時(shí)服務(wù)端處于CLOSE_WAIT狀態(tài)。
- 客戶端接收到服務(wù)端第二次揮手發(fā)送的ACK報(bào)文后,處于FIN_WAIT2狀態(tài)。
- 第三次揮手:如果服務(wù)器也想斷開連接了,和客戶端的第一次揮手一樣,給客戶端發(fā)送FIN報(bào)文,且指定一個(gè)序列號(hào)。此時(shí)服務(wù)端處于LAST_ACK狀態(tài)。
- 第四次揮手:客戶端收到FIN之后,一樣發(fā)送一個(gè)ACK報(bào)文作為應(yīng)答,且把服務(wù)端的序列號(hào)值+1作為自己ACK報(bào)文的應(yīng)答值,此時(shí)客戶端處于TIME_WAIT狀態(tài)。
- 服務(wù)器收到ACK報(bào)文后,就處于關(guān)閉連接了,處于CLOSED狀態(tài)。
四次揮手圖解
特別要注意的是TIME_WAIT狀態(tài),在服務(wù)器發(fā)送想要關(guān)閉連接的FIN-ACK報(bào)文后,客戶端不會(huì)立即關(guān)閉,而是等一段時(shí)間再關(guān)閉。原因就是要確保服務(wù)器接收到ACK報(bào)文。如果服務(wù)器沒有接受到,服務(wù)端會(huì)重新給客戶端發(fā)送FIN-ACK報(bào)文,客戶端再次接收到就知道之前的ACK報(bào)文丟失了,會(huì)再次發(fā)送ACK報(bào)文。
一些面試可能會(huì)問到的問題
ISN是固定的么?
ISN可以理解為序列號(hào)。ISN如果是固定的,攻擊者很容易猜出后序的確認(rèn)號(hào),因此ISN是動(dòng)態(tài)生成的。什么是半連接隊(duì)列?
我理解的這個(gè)問題的大概意思就是在兩個(gè)端進(jìn)行連接時(shí),請求的包會(huì)放在一個(gè)隊(duì)列中,客戶端發(fā)送的第一個(gè)請求和服務(wù)端連接的SYN包放入隊(duì)列中,此時(shí)服務(wù)端還未做出應(yīng)答的情況叫半連接隊(duì)列。三次握手全部完成后的叫全連接隊(duì)列。關(guān)于SYN-ACK重傳次數(shù)的問題
- 服務(wù)器發(fā)送完SYN-ACK包,如果未收到客戶端確認(rèn)包,服務(wù)器進(jìn)行首次重傳,等待一段時(shí)間仍未收到客戶端確認(rèn)包,進(jìn)行第二次重傳。
- 如果重傳次數(shù)超過系統(tǒng)規(guī)定的最大重傳次數(shù),系統(tǒng)將該連接信息從半連接隊(duì)列中刪除。
每次重傳的時(shí)間不一定相同,一般會(huì)是指數(shù)增長,例如時(shí)間間隔為1s,2s,4s,8s......
- 三次握手過程中可以攜帶數(shù)據(jù)么?
前兩次不可以,第三次可以。如果前兩次收發(fā)成功,就意味著客戶端與服務(wù)端之間可以建立連接,第三次就可以發(fā)送數(shù)據(jù)了。
我在網(wǎng)上看到的解釋是若第一次攜帶大量數(shù)據(jù)的話,會(huì)讓服務(wù)器更容易受到攻擊。因?yàn)楣粽卟粫?huì)管服務(wù)器是否收發(fā)數(shù)據(jù)正常,受到攻擊的服務(wù)端接收不到SYN報(bào)文,客戶端會(huì)重復(fù)發(fā)送,會(huì)讓服務(wù)器花費(fèi)更多的時(shí)間、內(nèi)存空間來接收。
三握四揮大概就是目前這些,主要是先將內(nèi)容搞清楚,自己能口述下來,后面有新的問題會(huì)繼續(xù)補(bǔ)充。