1. 程式人生 > >【TCP/IP】TCP

【TCP/IP】TCP

TCP介紹:

       TCP提供一種面向連線的、可靠的位元組流服務。面向連線,TCP一定要有三次握手的建立和四次握手的結束。可靠,TCP傳輸的每一個位元組都需要確認。位元組流服務,UDP叫資料報服務,應用層不管給UDP多大一個包,UDP就直接在這個基礎之上封裝UDP頭部、IP頭部、乙太網頭部,然後發走,網路上傳輸的資料和應用層給的資料是一一對應的。TCP是叫資料流,應用層給的資料,大了會把它拆小,小了會把它組裝大,然後在網路上發走,網路上傳輸的資料和應用層給的資料是沒有關係的。

       面向連線意味著兩個使用TCP的應用(通常時一個客戶和一個伺服器)在彼此交換資料之前必須先建立一個TCP連線

       在一個TCP連線中,僅有兩方進行彼此通訊,TCP的連線肯定是點對點的,TCP肯定是不支援組播和廣播的,UDP是可以支援的。

       應用資料被分隔成TCP認為最適合傳送的資料塊。應用層給的資料,大了會把它拆小,小了會把它組裝大,反正TCP會以它認為最合適的大小來發送。

       當TCP傳送出一個段後,它啟動一個定時器,等待目的端的確認收到這個報文段。如果不能即時收到一個確認,將重發這個報文段。

       當TCP收到發自TCP連線另一端的資料,它將傳送一個確認。這個確認不是立即傳送,通常將推遲幾分之一秒。為什麼要等呢?因為馬上給確認的話,有點浪費資源,發一個確認也是有消耗的,會有乙太網頭部、IP頭部、TCP頭部這些頭部就有幾十個位元組,還是會浪費頻寬的,但是如果等一會有可能這邊的主機也有資料要發給另一端,那樣就可以把確認同要發過去的資料用一個數據報一起發走,這樣效率就會更高。

       TCP校驗和校驗的是它的首部、偽首部和資料部分

       既然TCP報文段作為IP資料報來傳輸,而IP資料報的到達可能會失序,因此TCP報文段的到達也可能失序。如果必要,TCP將對收到的資料進行重新排序,將收到的資料以正確的順序交給應用層

       既然IP資料報會發生重複,TCP的接收端必須丟棄重複的資料

       TCP還能夠提供流量控制。TCP連線的每一方都有固定大小的緩衝空間,目的主機會告訴源端主機它的視窗大小是4096個位元組,如果說源端傳送的太快,目的端的緩衝空間有可能就滿了,目的主機就會告訴源端主機它的剩餘的緩衝區已經為0了,當源端知道為0後就不會再發了,等緩衝區空閒了之後會繼續再發。

       TCP的接收端只允許另一端傳送接收端緩衝區所能接納的資料。這將防止較快主機導致使較慢主機的緩衝區溢位

TCP的位元組流

      兩個應用程式通過TCP連線交換8bit位元組構成的位元組流。TCP不在位元組流中插入記錄識別符號。我們將這稱為位元組流服務。如果一方的應用程式先傳10位元組,又傳20位元組,再傳50位元組,連線的另一方將無法瞭解傳送方每次傳送了多少位元組。接收方可以分4次接收這80個位元組,每次接收20位元組。一端將位元組流放到TCP連線上,同樣的位元組流將出現在TCP連線的另一端。

     另外,TCP對位元組流的內容不作任何解釋。TCP不知道傳輸的資料位元組是二進位制資料,還是ASCII字元、EBCDIC字元或者其它型別資料。對位元組流的解釋由TCP連線雙方的應用層解釋。

TCP包首部:

       源埠和目的埠:各佔2位元組.埠是傳輸層與應用層的服務介面.傳輸層的複用和分用功能都要通過端口才能實現,這2個值加上IP首部中的源端IP地址和目的端IP地址唯一確定一個TCP連線

       序號:Seq序號,佔32位,用來標識從TCP源端向目的端傳送的位元組流,它表示在這個報文段中的第一個資料位元組。如果將位元組流看作再兩個應用程式間的單向流動,則TCP用序號對每個位元組進行計數。資料部分如果有100個位元組,seq就會加100,序號是32bit的無符號數,序號達到2的32次方後又從0開始。如果沒有資料只有首部還會加嗎?有可能會加,如果SYN或者FIN被置1就會加。因為SYN和FIN標誌都是有代價的,SYN標誌和FIN標誌都將消耗一個序號。傳送ACK無需任何代價,因為32bit的確認序號欄位和ACK標誌一樣,總是TCP的一部分。因此,我們看到一旦一個連結建立起來,這個欄位總是被設定,ACK標誌也總是被設定為1。

       確認號:Ack序號,佔32位,只有ACK標誌位為1時,確認序號欄位才有效,確認序號是上次已成功收到資料位元組序號加1。除了三次握手的第一個包SYN包是沒有ACK以外,其餘全部都有ACK位,也就是說除了第一個包以外,其他的包的確認序號都是有意義的。TCP為應用層提供全雙工服務。這意味資料能在兩個方向上獨立地進行傳輸。因此,連線的每一端必須保持在每個方向上的傳輸資料序號。

       首部長度:佔4位,(和IP首部長度一樣)它指出 TCP 報文段的資料起始處距離 TCP 報文段的起始處有多遠.單位是32 位字(以 4 位元組為計算單位)

       保留:佔 6 位,保留為今後使用,但目前應置為 0。有些黑客使用這6位上傳資料,來逃避檢測。但是現在有些東西會專門查這6個位,如果這6個位不是0,就會丟棄掉)

       緊急URG:當 URG=1 時,表明緊急指標欄位有效.它告訴系統此報文段中有緊急資料,應儘快傳送(相當於高優先順序的資料)

       確認ACK:只有當 ACK=1 時確認號欄位才有效.當 ACK=0 時,確認號無效。不要將確認序號Ack與標誌位中的ACK搞混了。

       PSH(PuSH):接收 TCP 收到 PSH = 1 的報文段,就儘快地交付接收應用程序,而不再等到整個快取都填滿了後再向上交付,一般現在的PSH位應用程式都不會理睬,收到了就受到了,大家都是一樣的,不能說攜帶了PSH位就要優先,因為應用層序也無法識別你這個PSH合不合法(惡意使PSH位置1),收到了也需要排隊。

       RST (ReSeT):當 RST=1 時,表明 TCP 連線中出現嚴重差錯(如由於主機崩潰或其他原因),必須釋放連線,然後再重新建立運輸連線

       同步 SYN:同步 SYN = 1 表示這是一個連線請求或連線接受報文

       終止 FIN:用來釋放一個連線.FIN=1 表明此報文段的傳送端的資料已傳送完畢,並要求釋放運輸連線

       視窗大小:佔2個位元組,視窗大小就是一個流控的技術,表明了接收方的剩餘緩衝空間的大小。TCP的流量控制由連線的每一端通過宣告的視窗大小來提供。視窗大小是一個16bit欄位,因而視窗大小最大為65535位元組。但是有視窗擴大因子來允許這個值按比例變化以提供更大的視窗(原理以後介紹,背景:由於現在的超高速網路,視窗大小最大為65535位元組已經遠遠不夠使用,因為在超高速網路中,一發送資料,接收端就會告訴傳送端視窗為0了,需要等待,一發送就需要等待。這樣效率就會很低,因此有了視窗擴大因子)。如果我的視窗大小是4096個位元組,不管你發幾個包過來,在沒得到我的ACK之前,你發的包總的大小最大為4096個位元組。這時候我回復ACK時更改視窗大小為0時,傳送端就不會發送資料,會等待接收端傳送一個ACK,告訴傳送端視窗大小閒置了。接受方對傳送方的速度進行限制,不能超過接收方的快取空間。

       檢驗和:佔2個位元組,檢驗和欄位檢驗的範圍包括首部和資料這兩部分.在計算檢驗和時,要在 TCP 報文段的前面加上 12 位元組的偽首部

       緊急指標:佔2個位元組,URG須置1,指出在本報文段中緊急資料共有多少個位元組(緊急資料放在本報文段資料的最前面)

       選項:長度可變.TCP 最初只規定了一種選項,即最大報文段長度 MSS(MTU-IP首部-TCP首部=1460).MSS 告訴對方 TCP:“我的快取所能接收的報文段的資料欄位的最大長度是 MSS 個位元組.” [MSS(Maximum Segment Size)是 TCP 報文段中的資料欄位的最大長度.資料欄位加上 TCP 首部才等於整個的TCP 報文段]

       TCP報文段中的資料部分是可選的

TCP資料在IP資料報中的封裝:

TCP可以表述為一個沒有選擇確認否認滑動視窗協議。我們說TCP缺少選擇確認是因為TCP首部中的確認序號表示發方已成功收到位元組,但還不包含確認序號所指的位元組,無法對資料流中選定的部分進行確認。例如,如果1~1024位元組已經成功收到,接收端會發送一個確認號為1025的報文確認,下一報文段中序號從1025~2048位元組的報文因為什麼原因沒有收到,在重發定時器還沒到期時,2049~3072位元組和後續的包已經到了,而且接收端也收到了。這時候接收端不能告訴傳送到我接收到了1~1024和2049~3072的包和後續的包,沒有收到1025~2048的包,接收端所能做的就是每接收到一段位元組的包後,過幾分之一秒傳送確認序號為1025的ACK給傳送端。當傳送端多次收到1025的ACK時,就會發現問題,這時候它可能(什麼原因不清楚)會把1025之後的包一起打包成一個大包傳送過去。或者等到重發定時器到期時,傳送端依次重新發送1025後續的包。沒有否認,當接收到接收到1~1024位元組的包後,在檢查CRC時校驗失敗把包丟了,這時候接收端不能告訴傳送端,已經接收到了1~1024位元組的包,因為CRC校驗失敗丟棄了。接收端只能傳送一個ACK為1的包告訴傳送端。要求傳送端傳送從1開始的包。