1. 程式人生 > >TCP UDP的區別

TCP UDP的區別

UDP與TCP的聯絡與區別:
    首先,這兩個都是運輸層協議
    {
        複習一下TCP四層模型:
        應用層、Telnet FTP email
        運輸層、TCP UDP
        網路層、ip ICMP igmp
        鏈路層 裝置驅動程式以及介面

        OSI七層
        
        應用層、表示層、會話層、
        傳輸層、
        網路層、
        資料鏈路層、物理層
    }

都是建立在ip之上的 TCP叫做流式套接字,UDP是報文套接字

    我們來看看為什麼要在ip之上,再做這樣的一步工作:
    ip中包含的資訊有:源ip 目的ip 然而一個網路中的程序的自由度是5:源ip 目的ip 源埠 目的埠 協議
    也就是說通過ip可以確定到計算機,但是沒有辦法將訊息傳送給具體的程序,而這個工作是交給TCP、UDP來完成的。
    也就是說。TCP、UDP都對ip來的資料進行的分發,交給上層應用。
    但是在這個過程中,TCP做的工作要比UDP多很多。
    
區別:tcp基於連線、UDP無連線。
    這就決定了TCP是P2P的,而UDP是支援一對一,一對多,多對一,多對多的:因為它根本就沒有連線(但是還是可以繫結埠),所以一個UDP套接字可以給其他任意套接字發東西。(這裡有一個問題叫做 確認UDP套接字。多個套接字繫結一個埠的時候,程式設計師希望負載均衡,但實際上是達不到的,因為每次都只會命中一個套接字。解決方案是開啟***選項)

這裡可以展開說連線與可靠是個什麼意思:我的理解是,TCP通過一系列機制(確認號,重傳等),儘管底層是不可靠的,但是不可靠發生的時候,TCP總可以糾正錯誤,保證使用者不需要操心資料的到來是亂序的,或者資料丟失了,使用者通過TCP建立連線之後,就可以放心的認為資料是對著的。  而TCP實現資料的可靠傳輸,是通過事先(三次握手)雙發約定好的一些資料(序列號,確認號,視窗大小)來完成的,這個東西就叫做連線,所以必然是點對點的,不可能對多,也不可能中通換物件。

但是UDP就不管這麼多,UDP完成的是最初的任務:原本的任務就是要解決IP無法將資料遞交給使用者期望的程序的問題的。所以UDP的結構相對簡單,佔用的資源少,通過ip+埠號,將資料發過去就好了,也不管資料丟失沒有,接收方也不管資料有沒有到達,有沒有重複。所有這也工作都要交給上層應用完成,也就是所謂的 網路中的某個問題,在各層都可以解決,如果底層不解決就讓上層解決。   既然UDP如此不方便,為什麼還要用UDP?尤其是我們熟悉的DNS似乎就是用UDP實現的?A:UDP開銷小,負載消耗小,在一些對精度要求不大,但是對速度要求大的場合,用UDP是合理的,即使一次失敗,重試的損失也不大。就拿DNS來說,它的任務就是通過網址找到IP然後返回,一次不行就再來一次,開銷很小,但是要儘量快,要降低伺服器負載。 但是DNS伺服器之間進行同步的時候用的就是TCP,這種場合要保證資料的正確。


最後總結一下:TCP是有連線的可靠的傳輸。
        UDP是無連線的不可靠的傳輸。
    

我們來看看TCP比UDP多做了哪些事情:
1.首先,在傳送資料的時候:
    TCP在傳送大塊資料的時候,會對資料進行分段,每個分段可以攜帶的資料為1個MSS(MSS是TCP雙發協定好的報文長度,這個長度既要儘量多的傳送使用者資料,又要避免IP分片,所以定一個合理的MSS是一件困難的事情),然後TCP將決定一次傳送多少段資料過去(這個時候就要考慮對方能處理多少資料——滑動視窗、以及網路的情況允許傳送多少資料——擁塞控制,這兩點其實就是TCP的流量控制與擁塞控制)  TCP在傳送大量小的資料的時候,為了充分利用頻寬,會啟動Nagle演算法(可以配置是否啟動),對較小的資料進行合併。(但是這樣就又會造成粘包問題,處理方法有短連線,應用層分包 等。。。)
    UDP傳送的時候無論大小,該發就發(所以沒有粘包問題,你看多好。。。)然而,如果UDP發的資料太多了,就會在底層發生分片。來算一算UDP發多少資料是合適的:
    {
        乙太網資料幀的長度必須在[46-1500]位元組之間,1500叫做MTU,最大傳輸單元,是有乙太網的物理特性決定的。然後,1500不包括鏈路層的首尾(18位元組),多以1500實際上是ip資料報的長度限制,IP首部20位元組,留給UDP或者TCP的有1480位元組,然後UDP自己的首部用掉8位元組,所以一個UDP中的資料應該不超過1472位元組。
        又因為英特網上執行的MTU標準是576位元組,同理,UDP的資料長度要限制在548位元組(576-20-8);

        {    
            乙太網協議頭,
            IP頭,
            TCP頭,
            UDP頭
        }    
    }
    如果UDP資料超過長度會怎麼樣?A:    首先會造成IP分片,接收方就要重組,使得效率變低,更加容易出現錯誤,如果資料錯誤或者丟失了,那麼UDP整個資料報就要丟掉。

    那麼可不可以稍微長一點?(手動狗頭)
    從IP包的總長度來看,ip包最大長度65536,減去頭(去掉頭就可以吃了),再減一個UDP頭,就有65507個。
    所以,不要超過1472(建議548),超過了就不要超65507.

2.然後,接收資料的時候:
    TCP會檢驗自己的ack與對面發來的seq,確認收到的資料是想要的資料(這裡邊有重複,丟失,亂序等)。如果不是想要的資料 比如我收到了1 2 3,接下來想要4,但是對面給我傳了5,那我只好再給對面傳一個(seq = x,ack=3)的報文,告訴對方,我這裡只確認到3,那對方就再給我傳一個4過來(具體實現沒有這麼簡單,上述的實際是一種丟包問題,具體可能要重出3次同樣的ack才會觸發重傳,或者超時重傳,或者用sack機制重傳。。。)
    然後,亂序的包,TCP重新整理好了順序。
    最後,TCP會告訴傳送方自己收到了哪些資料。


3.另外,在1中提到過,TCP實現了流量控制,網路擁塞控制。
    流量控制還好理解,雙方時刻關注對方的吞吐能力就可以了。網路的情況是難以預期的,難以觀測的,只能間接的瞭解網路的情況,TCP是如何做到擁塞控制的,還有TCP為何要控制擁塞,這是TCP應該完成的任務嗎?
    TCP正是通過一些量,間接的觀測出網路的狀況,來實現擁塞控制的。至於要不要控制?答案是要,因為TCP的出現會(重傳等)造成網路的擁塞,那麼TCP必須要負責。試想:如果某一時刻網路出現擁堵,TCP不管不顧,只認為自己的資料沒有送達,不斷地重傳,只會造成網路更加擁堵,惡性迴圈。
    TCP通過:慢啟動  擁塞避免  擁塞發生時的策略  快速恢復 這一系列策略,決定當前可以傳送的 段的數量,控制擁塞。

一句話:TCP可靠,控流,控制擁塞。

ps:有人說ping是基於UDP的,對嗎?
不對。儘管ping的特點和UDP很像:傳送的資料少,要求速度等,,,但是ping是基於原始套接字,使用ICMP協議完成的。和資料報套接字,流式套接字完全沒有關係,甚至從層次上看,ICMP是IP的子協議,ping的實現在網路層,TCP/UDP在運輸層,所以上述說法顯然是錯誤的。