TCP/UDP相關知識總彙

TCP如何保證可靠傳輸的?
確認機制:保證每一個數據包都能收到,
差錯檢驗:保證數據包的正確,
流量控制:保證接收方不會溢出。
順序編號:保證傳輸的有序性
 一、TCP/IP的可靠傳輸服務五個特徵:面向數據流、虛電路鏈接、有緩衝的傳輸、無結構的數據流、全雙工的鏈接。
  二、TCP採用了具備重傳功能的確定確認技術做爲可靠數據流傳輸服務的基礎。
  三、爲了提升數據流傳輸過程的效率,在上述基礎上引入滑動窗口協議,它容許發送方在等待一個確認以前能夠發送多個分組。滑動窗口協議規定只需重傳未被確認的分組,且未被確認的分組數最多爲窗口的大小。
  四、TCP功能
  TCP定義了兩臺計算機之間進行可靠的傳輸而交換的數據和確認信息的格式,以及計算機爲了確保數據的正確到達而採起的措施。
  五、TCP鏈接使用是一個虛電路鏈接,鏈接使用一對端點來標識,端點定義爲一對整數(host,port)其中host是主機的IP地址,port是該主機上TCP端口號。
  六、TCP使用專門的滑動窗口協議機制來解決傳輸效率和流量控制這兩個問題,TCP採用的滑動窗口機制解決了端到端的流量控制,但並未解決整個網絡的擁塞控制。
  七、TCP容許隨時改變窗口小,經過通告值來講明接收方還能再接收多少數據,通告值增長,發送方擴大發送滑動窗口;通告值減少,發送方縮小發送窗口。
  八、TCP的報文格式
  報文分爲兩部分:報頭和數據,報頭攜帶了所須要的標識和控制信息。
  確認號字段指示本機但願接收下一個字節組的序號;
  順序號字段的值是該報文段流向上的數據流的位置,即發送序號;
  確認號指的是與該報文段流向相反方向的數據流。
  九、TCP使用6位長的碼位來指示報文段的應用目的和內容
  URG緊急指針字段可用;ACK確認字段可用;PSH請求急近操做;RST鏈接復位;SYN同步序號;FIN發送方字節流結束。
  十、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,可靠性能夠在應用層實現
「流模式」與「數據包模式」在編程的時候有什麼區別呢?
一、TCP
打個比方比喻TCP,你家裏有個蓄水池,你能夠裏面倒水,蓄水池上有個龍頭,你能夠經過龍頭將水池裏的水放出來,而後用各類各樣的容器裝(杯子、礦泉水瓶、鍋碗瓢盆)接水。
上面的例子中,往水池裏倒幾回水和接幾回水是沒有必然聯繫的,也就是說你能夠只倒一次水,而後分10次接完。另外,水池裏的水接多少就會少多少;往裏面倒多少水,就會增長多少水,可是不能超過水池的容量,多出的水會溢出。
結合TCP的概念,水池就比如接收緩存,倒水就至關於發送數據,接水就至關於讀取數據。比如你經過TCP鏈接給另外一端發送數據,你只調用了一次write,發送了100個字節,可是對方能夠分10次收完,每次10個字節;你也能夠調用10次write,每次10個字節,可是對方能夠一次就收完。(假設數據都能到達)可是,你發送的數據量不能大於對方的接收緩存(流量控制),若是你硬是要發送過量數據,則對方的緩存滿了就會把多出的數據丟棄。
二、UDP
UDP和TCP不一樣,發送端調用了幾回write,接收端必須用相同次數的read讀完。UPD是基於報文的,在接收的時候,每次最多隻能讀取一個報文,報文和報文是不會合並的,若是緩衝區小於報文長度,則多出的部分會被丟棄。也就說,若是不指定MSG_PEEK標誌,每次讀取操做將消耗一個報文。
三、爲何
其實,這種不一樣是由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) ===================================================================== 七、簡述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(全是頭長,沒數據項)。   
相關文章
相關標籤/搜索