TCP/UDP相關知識總彙

TCP如何保證可靠傳輸的?
確認機制:保證每個數據包都能收到,
差錯檢驗:保證數據包的正確,
流量控制:保證接收方不會溢出。
順序編號:保證傳輸的有序性
 1、TCP/IP的可靠傳輸服務五個特徵:面向數據流、虛電路連接、有緩衝的傳輸、無結構的數據流、全雙工的連接。
  2、TCP採用了具有重傳功能的肯定確認技術作爲可靠數據流傳輸服務的基礎。
  3、爲了提高數據流傳輸過程的效率,在上述基礎上引入滑動窗口協議,它允許發送方在等待一個確認之前可以發送多個分組。滑動窗口協議規定只需重傳未被確認的分組,且未被確認的分組數最多爲窗口的大小。
  4、TCP功能
  TCP定義了兩臺計算機之間進行可靠的傳輸而交換的數據和確認信息的格式,以及計算機爲了確保數據的正確到達而採取的措施。
  5、TCP連接使用是一個虛電路連接,連接使用一對端點來標識,端點定義爲一對整數(host,port)其中host是主機的IP地址,port是該主機上TCP端口號。
  6、TCP使用專門的滑動窗口協議機制來解決傳輸效率和流量控制這兩個問題,TCP採用的滑動窗口機制解決了端到端的流量控制,但並未解決整個網絡的擁塞控制。
  7、TCP允許隨時改變窗口小,通過通告值來說明接收方還能再接收多少數據,通告值增加,發送方擴大發送滑動窗口;通告值減小,發送方縮小發送窗口。
  8、TCP的報文格式
  報文分爲兩部分:報頭和數據,報頭攜帶了所需要的標識和控制信息。
  確認號字段指示本機希望接收下一個字節組的序號;
  順序號字段的值是該報文段流向上的數據流的位置,即發送序號;
  確認號指的是與該報文段流向相反方向的數據流。
  9、TCP使用6位長的碼位來指示報文段的應用目的和內容
  URG緊急指針字段可用;ACK確認字段可用;PSH請求急近操作;RST連接復位;SYN同步序號;FIN發送方字節流結束。
  10、TCP的三次握手
  爲了建立一個TCP連接,兩個系統需要同步其初始TCP序號ISN。序號用於跟蹤通信順序並確保多個包傳輸時沒有丟失。初始序號是TCP連接建立時的起始編號。
  同步是通過交換攜帶有ISN和1位稱爲SYN的控制位的數據包來實現的。
  握手可由一方發起也可以雙方發起。
 
 
TCP與UDP的區別:
1.基於連接與無連接
2.對系統資源的要求(TCP較多,UDP少)
3.流模式與數據報模式
4.TCP保證數據正確性,UDP可能丟包,TCP保證數據順序
連接無連接:
連接(Connection)和無連接(Connectionless)是網絡傳輸中常用的術語,它們的關係可以用一個形象地比喻來說明,就是打電話和寫信。
打電話時,一個人首先必須撥號(發出連接請求),等待對方響應,接聽電話(建立了連接)後,才能夠相互傳遞信息。通話完成後,還需要掛斷電話(斷開連接),纔算完成了整個通話過程。寫信則不同,你只需填寫好收信人的地址信息,然後將信投入郵局,就算完成了任務。此時,郵局會根據收信人的地址信息,將信件送達指定目的地。
我們可以看到,這兩者之間有很大不同。打電話時,通話雙方必須建立一個連接,才能夠傳遞信息。連接也保證了信息傳遞的可靠性,因此,面向連接的協議必然是可靠的。無連接就沒有這麼多講究,它不管對方是否有響應,是否有回饋,只管將信息發送出去。就像信件一旦進了郵箱,在它到達目的地之前,你沒法追蹤這封信的下落;接收者即使收到了信件,也不會通知你信件何時到達。在整個通訊過程中,沒有任何保障。因此我們常說,面向無連接的協議也是不可靠的。當然,郵局會盡力將右鍵送到目的地,99%的情況信件會安全到達,但在少數情況下也有例外。
面向連接的協議比面向無連接的協議在可靠性上有着顯著的優勢,但建立連接前必須等待接收方響應,傳輸信息過程中必須確認信息是否傳到,斷開連接時需要發出響應信號等,無形中加大了面向連接協議的資源開銷。具體到TCP和UDP協議來說,除了源端口和目的端口,TCP還包括序號、確認信號、數據偏移、控制標誌(通常說的URG、ACK、PSH、RST、SYN、FIN)、窗口、校驗和、緊急指針、選項等信息,UDP則只包含長度和校驗和信息。UDP數據報比TCP小許多,這意味着更小的負載和更有效的使用帶寬。許多即時聊天軟件採用UDP協議,與此有莫大的關係。
TCP---傳輸控制協議,提供的是面向連接、可靠的字節流服務。當客戶和服務器彼此交換數據前,必須先在雙方之間建立一個TCP連接,之後才能傳輸數據。TCP提供超時重發,丟棄重複數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另一端。 
UDP---用戶數據報協議,是一個簡單的面向數據報的運輸層協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,但是並不能保證它們能到達目的地。由於UDP在傳輸數據報前不用在客戶和服務器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度很快。
用TCP還是UDP,那要看你的程序注重哪一個方面?可靠還是快速?
TCP UDP是兩個協議,簡單的說,TCP連接要對方確認的,而UDP卻不需要對方確認收到包,所以TCP連接更加安全,但是一般播放網絡流媒體使用UDP協議
傳輸層協議一般有TCP和UDP,TCP爲可靠傳輸,協議本身會保證數據傳輸的可靠,但爲此會付出很多額外的網絡開銷。UDP爲不可靠傳輸,所以傳輸效率比較高,本端只負責發送數據,不保證對端能否收到。對於UDP,可靠性可以在應用層實現
“流模式”與“數據包模式”在編程的時候有什麼區別呢?
1、TCP
打個比方比喻TCP,你家裏有個蓄水池,你可以裏面倒水,蓄水池上有個龍頭,你可以通過龍頭將水池裏的水放出來,然後用各種各樣的容器裝(杯子、礦泉水瓶、鍋碗瓢盆)接水。
上面的例子中,往水池裏倒幾次水和接幾次水是沒有必然聯繫的,也就是說你可以只倒一次水,然後分10次接完。另外,水池裏的水接多少就會少多少;往裏面倒多少水,就會增加多少水,但是不能超過水池的容量,多出的水會溢出。
結合TCP的概念,水池就好比接收緩存,倒水就相當於發送數據,接水就相當於讀取數據。好比你通過TCP連接給另一端發送數據,你只調用了一次write,發送了100個字節,但是對方可以分10次收完,每次10個字節;你也可以調用10次write,每次10個字節,但是對方可以一次就收完。(假設數據都能到達)但是,你發送的數據量不能大於對方的接收緩存(流量控制),如果你硬是要發送過量數據,則對方的緩存滿了就會把多出的數據丟棄。
2、UDP
UDP和TCP不同,發送端調用了幾次write,接收端必須用相同次數的read讀完。UPD是基於報文的,在接收的時候,每次最多隻能讀取一個報文,報文和報文是不會合並的,如果緩衝區小於報文長度,則多出的部分會被丟棄。也就說,如果不指定MSG_PEEK標誌,每次讀取操作將消耗一個報文。
3、爲什麼
其實,這種不同是由TCP和UDP的特性決定的。TCP是面向連接的,也就是說,在連接持續的過程中,socket中收到的數據都是由同一臺主機發出的(劫持什麼的不考慮),因此,知道保證數據是有序的到達就行了,至於每次讀取多少數據自己看着辦。
而UDP是無連接的協議,也就是說,只要知道接收端的IP和端口,且網絡是可達的,任何主機都可以向接收端發送數據。這時候,如果一次能讀取超過一個報文的數據,則會亂套。比如,主機A向發送了報文P1,主機B發送了報文P2,如果能夠讀取超過一個報文的數據,那麼就會將P1和P2的數據合併在了一起,這樣的數據是沒有意義的。
 
TCP握手協議

在TCP/IP協議中,TCP協議提供可靠的連接服務,採用三次握手建立一個連接。

第一次握手:建立連接時,客戶端發送syn包(syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確認;

第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;

第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。

完成三次握手,客戶端與服務器開始傳送數據,在上述過程中,還有一些重要的概念:

未連接隊列:在三次握手協議中,服務器維護一個未連接隊列,該隊列爲每個客戶端的SYN包(syn=j)開設一個條目,該條目表明服務器已收到SYN 包,並向客戶發出確認,正在等待客戶的確認包。這些條目所標識的連接在服務器處於Syn_RECV狀態,當服務器收到客戶的確認包時,刪除該條目,服務器 進入ESTABLISHED狀態。
Backlog參數:表示未連接隊列的最大容納數目。

SYN-ACK 重傳次數 服務器發送完SYN-ACK包,如果未收到客戶確認包,服務器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳,如果重傳次數超 過系統規定的最大重傳次數,系統將該連接信息從半連接隊列中刪除。注意,每次重傳等待的時間不一定相同。

半連接存活時間:是指半連接隊列的條目存活的最長時間,也即服務從收到SYN包到確認這個報文無效的最長時間,該時間值是所有重傳請求包的最長等待時間總和。有時我們也稱半連接存活時間爲Timeout時間、SYN_RECV存活時間。 
====================================================================
  現在,我們來看一個完整的流程,在一個TCP socket上系統調用connect究竟是如何建立起一個到對端的連接的。我們還是以實驗環境172.16.48.2向172.16.48.1的端口5002發起連接請求爲例。
    第一步,172.16.48.2向172.16.48.1發起連接請求,發送一個SYN段,指明目的端口5002,通告自己的初始序號(ISN,由協議棧 隨機產生的一個32位數),設置確認序號爲0(因爲還沒有收到過對端的數據),通告自己的滑動窗口大小爲5840(對端是5792,這似乎有問題,有待進 一步細查),窗口擴大因子爲2(在首部選項中),通告最大報文段長度爲1460(本地局域網),下面是數據內容(已剝去鏈路層的以太網首部和網絡層的IP 首部):
        數據內容                            含義
基本首部
        80 0e                               源端口(32782)
        13 8a                               目的端口(5002)
        00 00 07 bc                         初始序號ISN
        00 00 00 00                         確認序號
        a                                   首部長度
        0 02                                標誌位,SYN=1
        16 d0                               滑動窗口大小(5840)
        64 9e                               校驗和
        00 00                               緊急指針
TCP選項
        02 04 05 b4                         最大報文段長度(1460)
        04 02                               允許SACK
        08 0a 00 0a 79 14 00 00 00 00       時間戳(0x000a7914),回顯時間戳(0)
        01                                  佔位。
        03 03 02                            窗口擴大因子(2)
    第二步,172.16.48.1收到請求包,檢查標誌位,發現SYN=1,認爲這是一個初始化連接的請求,迴應這個SYN,同時也發送自己的SYN段(即 ACK,SYN同時置位)。因爲SYN本身要佔用一個序號(還有標誌FIN也要佔用一個序號)。所以,確認序號設置爲172.16.48.2的ISN加1 (即172.16.48.1期望收到來自172.16.48.2的下一個包的第一個序號爲0x07bd。同時也要通告自己的初始序號,滑動窗口大小,窗口 擴大因子,最大報文段長度等,下面是數據內容:
        數據內容                            含義
基本TCP首部
        13 8a                               源端口(5002)
        80 0e                               目的端口(32782)
        98 8e 40 91                         初始序號ISN
        00 00 07 bd                         確認序號(對端ISN+1)
        a                                   首部長度
        0 12                                標誌位,ACK=1, SYN=1
        16 a0                               滑動窗口大小
        65 d7                               校驗和
        00 00                               緊急指針
TCP選項
        02 04 05 b4                         最大報文段長度(1460)
        04 02                               允許SACK
        08 0a 00 3c 25 8a 00 0a 79 14       時間戳(0x003c258a),回顯時間戳(000a7914)
        01                                  佔位
        03 03 02                            窗口擴大因子(2)
    第三步,172.16.48.2對來自172.16.48.1的SYN段進行確認,至此,TCP三次握手協議完成,連接建立,在172.16.48.2收 到SYN段時,將自己對應的socket的狀態由TCP_SYN_SENT改爲TCP_ESTABLISHED,進入連接建立狀態,下面是數據內容:
        數據內容                            含義
        80 0e                               源端口(32782)
        13 8a                               目的端口(5002)
        00 00 07 bd                         序號(已不是ISN了)
        98 8e 40 92                         確認序號(對端ISN+1)
        8                                   首部長度(8*4=32,有12字節的選項)
        0 10                                標誌,ACK=1
        05 b4                               滑動窗口大小(1460,有問題?待確認)
        a5 8a                               校驗和
        00 00                               緊急指針

        01                                  佔位
        01                                  佔位
        08 0a 00 0a 79 14 00 3c 25 8a       時間戳(0x0a007914), 回顯時間戳(0x003c258a)
=====================================================================

7、簡述TCP三次握手過程,並說明爲什麼要3次握手
TCP 三次握手
TCP 連接是通過三次握手進行初始化的。三次握手的目的是同步連接雙方的序列號和確認號並交換 TCP 窗口大小信息。以下步驟概述了通常情況下客戶端計算機聯繫服務器計算機的過程:
1. 客戶端向服務器發送一個SYN置位的TCP報文,其中包含連接的初始序列號x和一個窗口大小(表示客戶端上用來存儲從服務器發送來的傳入段的緩衝區的大小)。
2. 服務器收到客戶端發送過來的SYN報文後,向客戶端發送一個SYN和ACK都置位的TCP報文,其中包含它選擇的初始序列號y、對客戶端的序列號的確認x+1和一個窗口大小(表示服務器上用來存儲從客戶端發送來的傳入段的緩衝區的大小)。
3. .客戶端接收到服務器端返回的SYN+ACK報文後,向服務器端返回一個確認號y+1和序號x+1的ACK報文,一個標準的TCP連接完成。
TCP 使用類似的握手過程來結束連接。這可確保兩個主機均能完成傳輸並確保所有的數據均得以接收
TCP Client Flags TCP Server 
1 Send SYN (seq=x) ----SYN---> SYN Received 
2 SYN/ACK Received  <---SYN/ACK---- Send SYN (seq=y), ACK (x+1)  
3 Send ACK (y+1) ----ACK---> ACK Received, Connection Established  
w: ISN (Initial Sequence Number) of the Client 
x: ISN of the Server  



==========================================================
  握手階段:   
  序號 方向   seq                           ack                         
  1  A->B           10000                           0           
  2         B->A           20000                         10000+1=10001         
  3         A->B           10001                         20000+1=20001   
  解釋:   
  1:A向B發起連接請求,以一個隨機數初始化A的seq,這裏假設爲10000,此時ACK=0   
    
  2:B收到A的連接請求後,也以一個隨機數初始化B的seq,這裏假設爲20000,意思是:你的請求我已收到,我這方的數據流就從這個數開始。B的ACK是A的seq加1,即10000+1=10001   
    
  3:A收到B的回覆後,它的seq是它的上個請求的seq加1,即10000+1=10001,意思也是:你的回覆我收到了,我這方的數據流就從這個數開始。A此時的ACK是B的seq加1,即20000+1=20001   
    
    
  數據傳輸階段:   
  序號  方向      seq                                     ack                       size   
  23           A->B                       40000                                   70000                     1514   
  24           B->A                       70000                     40000+1514-54=41460       54   
  25           A->B                       41460                     70000+54-54=70000           1514   
  26           B->A                       70000                     41460+1514-54=42920       54   
  解釋:   
  23:B接收到A發來的seq=40000,ack=30000,size=1514的數據包   
  24:於是B向A也發一個數據包,告訴B,你的上個包我收到了。B的seq就以它收到的數據包的ACK填充,ACK是它收到的數據包的SEQ加上數據包的大小(不包括以太網協議頭,IP頭,TCP頭),以證實B發過來的數據全收到了。   
  25:A在收到B發過來的seq爲41460的數據包時,一看到41460,正好是它的上個數據包的seq加上包的大小,就明白,上次發送的數據包已安全 到達。於是它再發一個數據包給B。這個正在發送的數據包的seq也以它收到的數據包的ACK填充,ACK就以它收到的數據包的seq(70000)加上包 的size(54)填充,即ack=70000+54-54(全是頭長,沒數據項)。   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章