1. 應用層數據被分割成大小最適合tcp發送的數據塊,便於tcp傳送
  2. 當tcp發出一個段後,它啟動一個定時器,等待目的端確認收到這個報文段,如果不能及時收到確認,將重發這個報文段。
  3. tcp保持首部和數據的校驗和。
  4. tcp數據報是基於ip數據報進行傳輸的,而ip數據報的到達順序可能會失序,所以tcp報文段的到達也可能會失序。tcp會對失序的數據包進行重排序,排序好後交給應用層。
  5. 當tcp接收端收到重複或損壞的數據包時則會丟棄數據報並請求發送端對數據包進行重傳。
  6. tcp的流量控制和擁塞控制。可能不太符合這個主題,但也是一個考慮方面。

上面是比較籠統的答案,但卻不太好理解。

下面從我的思考來解釋:

首先我們要理解tcp擁有以位元組為單位的滑動窗口,這個大家最好自己看看書,然後這個發送窗口的意思是:在未收到接收方的確認信號前,發送方可以連續把窗口內的數據都發送出去。凡是已經發送過的數據,在未收到確認的之前都必須暫時保留,以便在超時重傳時使用。

然後我們根據需要來看看tcp報文段首部的一些欄位:

序號:在一個tcp連接中傳送的位元組流中的每一個位元組都按順序編號,然後首部中的序號欄位值則指的是本報文段所發送的數據的第一個位元組的序號。

確認號:是期望對方下一個報文段的第一個數據位元組的序號,若確認號為n,則說明n-1為止的所有數據都已經正確收到。

確認ack:ack為1時確認號欄位有效。為0時確認號無效,tcp規定,在連接建立之後所有傳送的報文段都必須把ack置為1.

窗口:指明現在允許對方發送的數據量,也就是自己的接收窗口的大小。

tcp-payload:這個不是首部必須有的,它說明的是此報文段的數據報攜帶數據的大小,當不攜帶數據時則沒有這個。

Wireshark-TCP協議分析(包結構以及連接的建立和釋放) - CSDN博客 然後,如果你不太熟悉wireshark對於tcp數據報的分析的話建議先看看這個裡面的圖,這位大哥比較細心地畫出來了。

下面給幾張圖來分析一下:

注意裡面的sequence number 和pay-load的數量關係。

sequence number:0--1--105--1565

pay-load:105-1=104 1565-105=1460

這樣我想大家應該非常理解裡面的序號的意義了吧。這個是伺服器向客戶端發送網頁代碼和ajax請求之類的東西,後面是連續發送。中間很多都是以1460大小的數據發送,到最後只剩下892發送(圖太多,就沒有都上傳上來了,建議自己去嘗試觀察。)

上面這張是客戶端向伺服器發送的包,這裡的acknowledge number就是105,也就是前面說的期待伺服器發送過來的序號是105.

一個完整的信息段會被分為很多個數據包,然後這個信息段可以看成這按順序的四部分:1.已發送並收到確認、2.已發送但未收到確認、3.允許發送但尚未發送、4.不允許發送。2和3組成了發送方的發送窗口。這裡最好好好看看書不然很難理解它的精髓。

就是這樣一種來回序號的確認,讓數據包的傳輸可靠,不過這裡演示不出數據包損壞和重複接收數據包的情況,此時應該會請求相應的重傳和丟棄。對於不按序到達的數據,tcp通常都是先臨時存放在接收窗口中,等待位元組流中所缺少的位元組收到後,再按序交付上層的應用進程。 這裡在首部有個可選的欄位sack,就是存放缺失的位元組段的邊界的,告訴發送方哪些沒有接收到。然而,sack文檔並沒有指明發送方應當怎樣響應sack。所以大多數的實現還是重傳所有未被確認的數據塊。

由上面也可以看到,並不是發送方每發送一次數據接收方都會返回一次確認,接收方會有累計確認的功能,這樣可以減少傳輸的開銷。在接收方認為合適或需要攜帶數據給發送方時再把確認信號發送過去。但是,這裡要注意,這個確認信號的推遲發送時間不能超過0.5秒(tcp標準規定),因為你推遲地太久地話可能會讓發送方以為數據沒有發送過去,導致發送方對數據進行重傳,浪費時空間的效率。

這裡注意,接收方只能對按序收到的數據中的最高序號給出確認!!

最後是tcp首部的校驗和數據,這裡可以校驗裡面的數據是否出現差錯,如果出錯了就重傳。

所以,總結一下我的觀點:

1.tcp首部有校驗和,當接收方根據校驗和發送數據包有錯會返回一個請求對該數據包進行重傳。

2.tcp首部中的序號,把大數據包分成合適數據包發送過去,然後接收方進行組合傳給應用層。然後配合確認號,確認收到相應的數據報,所以接收方會有定時器進行相應重傳機制。當然這裡也包括對損壞的數據包的重傳。

歡迎交流討論。


推薦閱讀:
相關文章