圖1:TCP 套接字的數(shù)據(jù)交換過程
上圖給出了主機A分2次(分2個數(shù)據(jù)包)向主機B傳遞200字節(jié)的過程。首先唤反,主機A通過1個數(shù)據(jù)包發(fā)送100個字節(jié)的數(shù)據(jù)凳寺,數(shù)據(jù)包的 Seq 號設(shè)置為 1200。主機B為了確認這一點彤侍,向主機A發(fā)送 ACK 包肠缨,并將 Ack 號設(shè)置為 1301。為了保證數(shù)據(jù)準確到達盏阶,目標機器在收到數(shù)據(jù)包(包括SYN包晒奕、FIN包、普通數(shù)據(jù)包等)包后必須立即回傳ACK包名斟,這樣發(fā)送方才能確認數(shù)據(jù)傳輸成功脑慧。
此時 Ack 號為 1301 而不是 1201,原因在于 Ack 號的增量為傳輸?shù)臄?shù)據(jù)字節(jié)數(shù)砰盐。假設(shè)每次 Ack 號不加傳輸?shù)淖止?jié)數(shù)闷袒,這樣雖然可以確認數(shù)據(jù)包的傳輸,但無法明確100字節(jié)全部正確傳遞還是丟失了一部分岩梳,比如只傳遞了80字節(jié)囊骤。因此按如下的公式確認 Ack 號:Ack號 = Seq號 + 傳遞的字節(jié)數(shù) + 1
上圖表示通過 Seq 1301 數(shù)據(jù)包向主機B傳遞100字節(jié)的數(shù)據(jù),但中間發(fā)生了錯誤列疗,主機B未收到滑蚯。經(jīng)過一段時間后,主機A仍未收到對于 Seq 1301 的ACK確認抵栈,因此嘗試重傳數(shù)據(jù)告材。為了完成數(shù)據(jù)包的重傳,TCP套接字每次發(fā)送數(shù)據(jù)包時都會啟動定時器竭讳,如果在一定時間內(nèi)沒有收到目標機器傳回的 ACK 包创葡,那么定時器超時,數(shù)據(jù)包會重傳绢慢。上圖演示的是數(shù)據(jù)包丟失的情況灿渴,也會有 ACK 包丟失的情況洛波,一樣會重傳。
重傳超時時間(RTO, Retransmission Time Out)
這個值太大了會導致不必要的等待骚露,太小會導致不必要的重傳蹬挤,理論上最好是網(wǎng)絡(luò) RTT 時間,但又受制于網(wǎng)絡(luò)距離與瞬態(tài)時延變化棘幸,所以實際上使用自適應(yīng)的動態(tài)算法(例如 Jacobson 算法和 Karn 算法等)來確定超時時間焰扳。往返時間(RTT,Round-Trip Time)表示從發(fā)送端發(fā)送數(shù)據(jù)開始误续,到發(fā)送端收到來自接收端的 ACK 確認包(接收端收到數(shù)據(jù)后便立即確認)吨悍,總共經(jīng)歷的時延。
重傳次數(shù)
TCP數(shù)據(jù)包重傳次數(shù)根據(jù)系統(tǒng)設(shè)置的不同而有所區(qū)別蹋嵌。有些系統(tǒng)育瓜,一個數(shù)據(jù)包只會被重傳3次,如果重傳3次后還未收到該數(shù)據(jù)包的 ACK 確認栽烂,就不再嘗試重傳躏仇。但有些要求很高的業(yè)務(wù)系統(tǒng),會不斷地重傳丟失的數(shù)據(jù)包腺办,以盡最大可能保證業(yè)務(wù)數(shù)據(jù)的正常交互焰手。最后需要說明的是,發(fā)送端只有在收到對方的 ACK 確認包后怀喉,才會清空輸出緩沖區(qū)中的數(shù)據(jù)书妻。