部分參考:https://blog.csdn.net/zhangdaisylove/article/details/47294315
源端口號:佔2個字節,就是發起方的port
目的端口號:佔兩個字節,接收方的port
seq:佔4個字節,發送方標記自己的segment的序列號,用以各個tcp報文的順序。
ack:佔4個字節,應答號,通常解釋爲期待接收到下一個序列號的報文,個人理解爲這是第一個接收方未接收到的包
4位首部長度:佔 4bit,表示tcp頭部長度,單位爲4個字節。
6位保留位
標誌位:分別爲URG、ACK、PSH、RST、SYN、FIN,
URG表示本包數據有緊急數據,ACK表示本包中ack值有效,PSH表示本包數據需要立即把本包數據從緩存區送出去,
RST表示連接有錯誤,重置連接,SYN表示建立連接,FIN表示結束連接。
16位窗口大小:表示接受方可以接受對方數據的緩存區大小。
16位校驗和:
16位緊急指針:當URG被置位時,該值表示從開始到該值所指字節都是緊急數據。
一:滑動窗口
有時候接受方的緩存區已經滿了,這個時候如果繼續發送數據,那麼接收方就會把數據丟棄掉,這樣會白白浪費流量,所以在TCP的ACK中每次都會通知發送方自己可以接受的數據大小,也就是TCP報文中的16位窗口值,如果窗口變成了零以後,那麼發送方就會停止發送,一直等到接收方可以接收數據,但是一直等待會出問題,如果其中ACK丟了,就會以爲對方還不能接收數據,這個時候發送方可以發送窗口探測包。其中數據爲0。
解釋:當發送方收到接收方發來應答包後,應答號ack,加上報文中的窗口值減一,就是目前接受方的緩存最大可接受的數據包序列號,如下圖ack=4,窗口值爲6,那麼4+6-1=9,也就是說發送知道目前最大可發送的數據包序號只能到9。
這就是滑動窗口,ack表示了窗口的左邊界,ack+wind-1是窗口的右邊界,即[ack,ack+win-1]區間,
目前只可以發送seq屬於[ack,ack+win-1]區間的tcp數據包。由於ack一直變化,所以[ack,ack+win-1]屬於向右滑動。
二:擁塞控制:
擁塞控制的目的避免網絡擁塞,同時最大化網絡利用率。不能一開始就發送大量數據到網絡,以免造成網絡擁塞,要對網絡進行試探,並實時根據網絡狀態控制發送量,這就是擁塞控制的目的。這是一種試探網絡狀態的算法,判斷當前網絡最大可以一次性發送多少個MSS且不會導致網絡擁塞。(MSS是TCP最大段大小,根據MTU計算,MTU爲1500,則MTU-IP頭-TCP頭=1460)。
1. 如何實現:
擁塞控制的實現就是調整兩個值:擁塞窗口值(cwnd),擁塞窗口閾值(ssthresh)。擁塞窗口閾值ssthresh是前一次擁塞時cwnd值的一半,建立連接之初,擁塞窗口cwnd=1,閾值ssthresh可以爲無限大(因爲不知道網絡發送流量上限是多少,無法確定,設爲一個較大值(ssthresh=65536),進行試探,或者指定其他適當值)。
2. 調整兩個值的流程:
1)連接建立之初只發送一個數據包(cwnd=1),假定當前狀態是最差,這樣對網絡負荷影響最小(避免擁塞)。
2)如果沒有出現應答超時或者重複應答(網絡沒有擁塞,那麼繼續加大流量(最大化網絡利用率,同時要避免擁塞)
- 此時當擁塞窗口在其閾值之下時(cwnd<ssthresh),繼續翻倍增長窗口(cwnd=2*cwnd就是翻倍發送量)
- 如果在閾值之上(cwnd>=ssthresh),則線性增加窗口值(cwnd=cwnd+1)。
進入2);如果出現擁塞則進入3)。
3)出現應答超時或者重複應答(網絡已擁塞,探測到擁塞值),如果
- 如果應答超時,將擁塞窗口閾值變爲超時時的擁塞窗口的值的1/2(ssthresh=cwnd/2),將擁塞窗口值變爲1(cwnd=1),並(網絡狀況很差,避免擁塞,立即將窗口設爲0)
- 如果重複應答,將擁塞窗口閾值變爲重複應答時擁塞窗口值的1/2(ssthresh=cwnd/2),然將擁塞窗口值變爲閾值並加3(cwnd=ssthresh+3),然後。(網絡狀況有點差,但是沒有很差,窗口縮半)
進入2)。
解釋:這是發送方主機主動控制的值,是爲發送方的TCP建立的一個受網絡狀況而定的窗口。每次發送數據時都會根據擁塞窗口和滑動窗口(對方ack應答包中的16位窗口大小)大小對比,選取值小的那一個作爲數據包的長度值。
擁塞控制是最大化網絡利用率,流量大小隨網絡狀態動態調整。開始值要小但是要快速增加(指數增加),當到達閾值時流量增速要放緩(線性增加)以免很快又造成網絡擁塞,另外由於第一次建立連接ssthresh的值較大,一般第一次 只會出現進翻倍發送。典型圖如下所示:
總結:擁塞窗口閾值總是變爲發生擁塞時的1/2(ssthresh=cwnd/2),擁塞窗口值在應答超時時變爲0,在重複應答時變爲當前值1/2後再加3(即新閾值加3)。
三、擁塞窗口和滑動窗口
擁塞窗口也可以決定出一個最大的發送序列號,滑動窗口也可以,需要二者取其小。另外擁塞窗口是發送方主動感知網絡狀態,進而決定的發送數據的流量,而滑動窗口是接收方告知發送方的。
四、其他
3:超時控制,窗口控制,流量控制,擁塞控制對比
1)超時控制,只是在每一個數據都要確定收到 ACK,沒有收到ACK超過時間限定就會重發。
2)窗口控制,會對持續收到的同一個ACK三次以後重發數據,並且如果長時間沒有收到ACK,那麼也會重發數據。
3)流量控制,就是確認接收方是否有足夠緩存接受數據,否則一個勁發會浪費網絡流量。
4)擁塞控制,這個是試探網絡是否可以接受目前的數據發送大小。
5)網絡和主機緩存一起決定着數據發送數據的大小。
4:延遲應答
有時候沒必要對每個數據都立刻發送ACK,可以稍微等待下一個數據也收到了,然後發送ACK,或者等待時間過長也發送ACK。
5:捎帶應答:
就是把應答放在其他的數據包中一起發送過去。
6:半關閉:
TCP 的 shutdown() 可以停留在一個只接收數據,而不寫數據的狀態中,這個時候狀態稱爲半關閉。