tcp協議,全稱傳輸控制協議,處在傳輸層之中,下層為網路層,上層為應用層。
udp協議,全稱使用者資料報協議,所處位置與tcp相同。
而談到傳輸層,則必須談到埠號,埠號的名稱可能沒有ip位址那麼響亮,但是它仍然非常重要,在tcp/ip協議中,用「源ip」,「源埠號」,「目的ip」,「目的埠號」,「協議號」這樣乙個五元組來標識乙個通訊。
常見的知名埠號:
upd協議格式:
udp特點:
基於udp的應用層協議:
tcp協議格式:
源/目的埠號:表示資料從哪個程序來,到哪個程序去。
這也是的tcp/udp知道自己最終將資料交付給上層協議的哪乙個應用程序。無論是哪一層協議都要解決這兩個問題:
將資料交付給上層的哪乙個協議?(復用與分用)
如何將報頭與報文分離?(udp採用的是定長報頭)
在看32位序號和確認序號之前,我們先看下面的一行:
4位tcp報頭長度,表示該tcp頭部有多少個32位(4位元組),這4位表示的最大長度為15*4 = 60,tcp頭部的最大長度就是60位元組,其中包括固定部分和可選項,這裡的4位tcp報頭長度中的15表示15個4位元組。
6位標誌位:
ack:確認號是否有效
psh:提示接收方應用程式立刻從tcp緩衝區把資料讀走
rst:對方要求重新建立連線,我們把攜帶rst標識的稱為復位段報文
syn:請求建立連線
fin:通知對方,本端要關閉了,攜帶fin標識的被稱為結束報文段
16位校驗和:傳送端填充,crc校驗。接收端校驗不通過,則認為資料有問題。此處的校驗和不光包含tcp首部,也包含tcp資料部分。
連線管理機制:
正常情況下,tcp要經過三次握手建立連線,四次揮手斷開連線,在這期間通訊雙方可能會出現11種狀態。
首先在服務端會呼叫socket()分配乙個檔案描述符用於進行通訊,然後呼叫bind()繫結伺服器埠位址,呼叫listen()函式進入監聽狀態,此時的套接字為被動套接字,只能等待別的套接字來連線,而不能主動進行連線。關於相關函式可以看點這裡。
在伺服器進入監聽狀態後,客戶端這樣就可以呼叫socket()得到乙個檔案描述符,這是乙個主動套接字,可以使用connect()發起連線請求,這就進入了三次握手的過程。
那麼為什麼是三次握手,而不是四次握手,五次握手呢?
這是因為雙方進行通訊的時候,都需要維護相應是資料結構來維持通訊,這就需要花費一定的資源,如果通訊過程中,發生了資料丟失,那麼造成的後果由誰來承擔。
三次握手的設計導致最後一次握手資料丟失,只有客戶端會花費資源維持通訊,而伺服器不會,因為伺服器可能同時會面臨這大量的連線,所以壓力比較大,而客戶端所維持的連線相對來說造成的影響微小,所以最終採取了三次握手的策略。
那麼最後一次客戶端的ack丟了,客戶端會認為連線已經建立好了,然後傳送資料進行通訊,此時伺服器認為這不是已經建立好的連線,就會傳送rst標誌位,告訴客戶端重新建立連線。
四次揮手的過程是由雙方任意一方主動斷開連線,主動斷開的一方會進入time_wait狀態,如果是伺服器,應該避免進入這一狀態,可以採用setsockopt()設定socket描述符的選項so_reuseaddr為1,表示允許建立埠號相同但ip位址不同的多個socket描述符。
time_wait的時間為2msl,msl是tcp報文的最大生存時間,因此time_wait持續存活2msl的話就能保證在兩個傳輸方向上尚未被接收或遲到的報文段都已經消失了。
如果此時三次握手成功,那麼通訊雙方就可以進行正常通訊。而在通訊的時候,tcp作為乙個可靠的協議,是如何保證可靠的呢?
所謂可靠,就是指資料不能發生丟失,亂序,重複。此處tcp引入了確認應答機制,發揮作用的就是報頭中的序號和確認序號。
tcp將每個位元組的資料都進行了編號,即為序列號,每乙個ack都帶有對應的確認序列號,意思是告訴傳送方,我已經收到了哪些資料,下一次你從**開始發。
那麼如果主機a傳送資料給主機b之後,因為網路擁塞等原因,資料無法到達主機b,那麼主機a在乙個特定的時間間隔內沒有收到主機b的確認應答,就會重發。這種機制,被稱為超時重傳機制。
因此主機b可能會收到重複的資料,那麼tcp協議會根據序號把重複的包丟棄掉。
對於超時重傳的時間間隔,tcp為了保證無論在任何環境下都能比較高效能的通訊,因此會動態計算這個最大超時時間。
以上說的兩種策略都保證了可靠性,但是也影響了效率,因此tcp協議還引入和滑動視窗、流量控制以及擁塞控制來提高效率。
另外,與udp不同的是,tcp協議是面向位元組流的,也是是說,在傳送和接收的資料中,會像水流一樣沒有固定的格式。
這就會產生新的問題,粘包問題。
通常產生粘包問題的情況有以下幾種:
應用層交付的資料較大,大於傳送緩衝區的視窗大小,無法一次傳送,故需要分片。
mac層有mtu(最大傳輸單元),ip層判斷上層協議交付下來的資料是否需要分片。
一旦資料分片,那麼接收方可能一次拿到的資料就不是乙個完整的資料,這就是粘包問題。
解決粘包問題的方案如下:
定長報文,無論要傳送的資料大小為多少,固定的長度為一條訊息,接收方按固定長度讀取,單次傳送的訊息不夠定長的可以用0填充。
報頭中新增報文的長度,接收方通過讀取報頭知道本次報文的長度,進而解決粘包問題。
tcp小結:
為什麼tcp這麼複雜?因為要保證可靠性,同時又要盡可能的提高效能。
可靠性:
提高效能:
TCP協議與UDP協議
1 提供ip環境下的資料可靠傳輸,有效流控,全雙工操作 資料在兩個方向上能同時傳遞 多路復用服務,是面向連線,端到端的傳輸 2 面向連線 正式通訊前必須要與對方建立連線。3 tcp支援的應用協議 telnet 遠端登入 ftp 檔案傳輸協議 smtp 簡單郵件傳輸協議 tcp用於傳輸資料量大,可靠性...
TCP協議 UDP協議
tcp是面向連線的傳輸層的協議,它在程序互動時,會建立乙個鏈結,然後在傳輸資料之後會取消連線,tcp的鏈結是虛連線。每一條tcp連線只能有兩個端點,只能是點對點的資料鏈結,不能進行廣播。tcp提供可靠的按時交付的 無差錯的 不重複的 按序到達的服務 可靠有序 不丟不重 tcp提供全雙工通訊 傳送快取...
TCP協議與UDP協議的區別
tcp建立連線要進行3次握手,而斷開連線要進行4次 1 當主機a完成資料傳輸後,將控制位fin置1,提出停止tcp連線的請求 2 主機b收到fin後對其作出響應,確認這一方向上的tcp連線將關閉,將ack置1 3 由b 端再提出反方向的關閉請求,將fin置1 4 主機a對主機b的請求進行確認,將ac...