UDP 和 TCP 的 socket 分別一般用在什麼地方?
UDP 的使用範圍很窄,而且編程比 TCP 難多了:
- 你真的很在乎延遲,不能忍受重傳,那麼就用UDP,例如 NTP 協議。重傳NTP消息純屬添亂。
- 你真的不在乎可靠性,丟一些包也不需要重傳,那麼就可以用 UDP。例子我想不出來。有人說音頻或視頻流可以用UDP,不過據我看來各大視頻網站都用HTTP協議,而HTTP是基於TCP的。
- 你需要NAT穿透,那麼不得不用UDP。
- 其他情況,一旦程序要自己做重傳,你都是在用UDP模擬出蹩腳的TCP,還不如直接用TCP呢。
總之:使用 UDP 需要有強大到不容置疑的理由,when in doubt, use TCP.
一些協議,出於歷史原因,受當時技術和網路條件限制,選擇了基於UDP實現,其選擇的理由現在很可能已經不再成立了。因此「xxx協議用UDP」不是你現在寫網路應用程序也該用UDP的理由,除非你本身就是在實現xxx協議。
另外,那些說TCP比UDP慢、效率低的,你拿UDP寫個程序,把千兆網帶寬打滿(TCP等價的代碼只有兩行:客戶端 while (true) { send(...); } 服務端 while (true) { recv(...); }。),且不說你的程序會有多複雜,先看看goodput到底是不是比TCP大、CPU使用率是不是比TCP低嘛。在絕大部分場景都開始直接選擇TCP的時候,我要提一個非常窄的UDP應用場景:翻嬙
從需求上說,翻嬙的業務場景對協議有如下要求:
1. 不被嬙認為是敏感流量或者即使被認為是敏感流量也不能被重置
2. 協議夠輕,載荷比高(像Tor這種其實非常不適合做此用途)
UDP本身無連接,所以即使被認為是敏感流量,也無法被重置;
UDP作為協議「外殼」,裡面往往搭載的是基於TCP的協議(比如http),TCP自己有檢驗和重傳機制,不需要外殼操心。
針對UDP作為協議外殼的封禁方法,只有drop,或者把IP徹底牆掉…不管哪個,都要比過去發送reset重的多——過去只要丟一個reset出去瀏覽器起碼「閉嘴」幾分鐘,而現在UDP裡面所攜帶的載荷不會收到reset,該發還發。
所以在這個場景里,UDP還是蠻有用的。如果用UDP通信時,穿個薄薄羽絨服讓怪物看不清裡面是什麼,就足夠了…(我用RC4這種「不安全」的加密協議我會亂說?)
我翻出去不是為了看啥或者說啥,我就是想跟丫死磕…
算了,不匿了
======時隔兩年更新========丟包這個事取而代之的路由黑洞
但我判斷的沒錯,還是不太好處理。
而且誕生了兩個靠udp通信的好工具,shadowVPN和kcp
尤其是kcp,乾脆就是為了自己控制發包速度
陳碩說的基本是對的,我補充一下他所說的可以用 UDP 的情況。
1,
實時音視頻是可以而且應該用 UDP 的,一方面因為它常常涉及到網路穿透,另外一方面它不需要重傳。——我需要實時的看到你的圖像跟聲音,至於中間丟一幀什麼的完全不重要。而為了重傳往往會造成延遲與不同步,考慮一下,某一幀因為重傳,導致0.5秒以後才到,那麼整個音視頻就延遲了0.5秒。
考慮一下接收方看視頻,如果使用 TCP 導致視頻的中間延遲了0.5秒,只要我不按「快進」鍵,那麼後續的視頻全都會比發送方延遲0.5秒。這種延遲是累加的,隨著持續丟幀,延遲會越來越大,達到數秒,甚至分鐘級,這會嚴重影響實時音視頻的用戶體驗。
因此「實時音視頻聊天」功能通常都會使用 UDP 實現。
2,
網路真的非常非常可靠,以至於你完全不需要考慮 UDP 丟包問題的情況。
典型的例子應該是專門為有線區域網設計的協議。
3,
另外一個問題是 TCP 是純粹的流式數據,所以制定傳輸協議的時候,接受方需要自行判定一個包的開始和結束,因為你完全可能接受到半個包或者兩個包。——如果數據報的起止判定對你具體的程序會成為大問題,也可以考慮 UDP。
至於其他的情況, 「 when in doubt, use tcp 」
有些時候UDP比TCP更有優勢。
1,網速的提升給UDP穩定性提供可靠網路保障
CDN服務商Akamai(NASDAQ: AKAM)報告從2008年到2015年7年時間,各個國家網路平均速率由1.5Mbps提升為5.1Mbps,網速提升近4倍。網路環境變好,網路傳輸的延遲、穩定性也隨之改善,UDP的丟包率低於5%,如果再使用應用層重傳,能夠完全確保傳輸的可靠性。
2,對比測試結果UDP性能優於TCP
為了提升瀏覽速度,Google基於TCP提出了SPDY協議以及HTTP/2。Google在Chrome上實驗基於UDP的QUIC協議,傳輸速率減少到100ms以內。
Google採用QUIC後連接速率能有效提升75%。
Google搜索採用QUIC後頁面載入性能提升3%。
YouTube採用QUIC後重新緩衝次數減少了30%。
3, TCP設計過於冗餘,速度難以進一步提升
TCP為了實現網路通信的可靠性,使用了複雜的擁塞控制演算法,建立了繁瑣的握手過程以及重傳策略。由於TCP內置在系統協議棧中,極難對其進行改進。
4, UDP協議以其簡單、傳輸快的優勢,在越來越多場景下取代了TCP
4.1 網頁瀏覽
使用UDP協議有三個優點 :
- 能夠對握手過程進行精簡,減少網路通信往返次數;
- 能夠對TLS加解密過程進行優化;
- 收發快速,無阻塞。
4.2 流媒體
採用TCP,一旦發生丟包,TCP會將後續包緩存起來,等前面的包重傳並接收到後再繼續發送,延遲會越來越大。基於UDP的協議如WebRTC是極佳的選擇。
2010年google 通過收購 Global IP Solutions,獲得了WebRTC(網頁實時通信,Web Real-Time Communication)技術,用於提升網頁視頻速率。
4.3 實時遊戲
對實時要求較為嚴格的情況下,採用自定義的可靠UDP協議,比如Enet、RakNet(用戶有sony online game、minecraft)等,自定義重傳策略,能夠把丟包產生的延遲降到最低,盡量減少網路問題對遊戲性造成的影響。
採用UDP的經典遊戲如FPS遊戲Quake、CS,著名的遊戲引擎Unity3D採用的也是RakNet。
4.4 物聯網
2014年google旗下的Nest建立Thread Group,推出了物聯網通信協議Thread,完善物聯網通信。
採用UDP有3個關鍵點:
- 網路帶寬需求較小,而實時性要求高;
- 大部分應用無需維持連接;
- 需要低功耗。
全球將近50%的人都在使用互聯網,人們不斷的追求更快、更好的服務,一切都在變化,在越來越多的領域,UDP會搶佔TCP的主導地位。
曾經讀gtalk開源項目libjingle的源碼時看到文件傳輸功能是用的udp協議
你一定會問,什麼?文件傳輸這種可靠性要求如此高的場景怎麼可能用udp這麼不可靠的協議呢?
這裡就用到udp一個得天獨厚的優勢了,打洞!
gtalk的文件傳輸會嘗試用戶p2p直連,這樣可以省去伺服器開銷
但用戶都是處於各自內網的情況下無法建立起tcp連接,只能用udp打洞的方式通信
所以libjingle中用udp實現了假冒tcp的可靠協議,有興趣的同學可以去看下PseudoTcp類的實現
發送文件方用PseudoTcp創建http server,接收方用PseudoTcp封裝的http client去下載
Socket,指的是TCP/IP模型中,傳輸層UDP和TCP兩個協議使用的地址。這個地址的格式為[發送端IP地址,發送端埠號:接收端IP地址,接收端埠號]。所以Socket用於傳輸層的定址,你在編寫網路程序的時候就需要用到。
udp處理數據報,tcp處理網路流。
讀udp socket 一次返回一個報文
讀TCP socket不一定能讀到一個完整的報文
udp不保證報文到達的先後順序,不保證是否有報文丟失
tcp保證寫入流的數據按順序被讀出來
tcp可靠性高,效率低
udp效率高,可靠性低
0、TCP是面向流字元的,數據流間無邊界;UDP是面向分組的,分組間有明確的邊界。
對於TCP,發送一串數字(1,2,3,4,5),接收時有可能變成兩次(1,2)和(2,4,5),或者變成任意接收方式,協議棧只保證接收順序正確;UDP發送一個分組,接收方或者接收完全失敗,如果成功整個分組都會接收到。
1、TCP是面向連接的,UDP是無連接的。類比於打電話和發電報的關係。
TCP建立一個連接需要3次握手IP數據包,斷開連接需要4次握手。另外斷開連接時發起方可能進入TIME_WAIT狀態長達數分鐘(視系統設置,windows一般為120秒),在此狀態下連接(埠)無法被釋放。
2、TCP是可靠的,通過數據校驗保證發送和接收到的數據是一致的;UDP是不可靠的,發送一串數字分組(1,2,3)可能接收到時就變成(1,0,0)了,做UDP連接時需要自己做數據校驗。
3、TCP數據是有序的,以什麼順序發送的數據,接收時同樣會按照此順序;UDP是無序的,發出(1,2,3),有可能按照(1,3,2)的順序收到。應用程序必須自己做分組排序。
4、TCP因為建立連接、釋放連接、IP分組校驗排序等需要額外工作,速度較UDP慢許多。TCP適合傳輸數據,UDP適合流媒體。
5、UDP比TCP更容易穿越路由器防火牆。打個比方:
TCP就像是兩個人傳遞球
A:我要傳球給你了哦,你準備好了嗎?
B:準備好了!
A:開始傳一號球
B:收到!
A:二號球
B:收到
....
A:傳完了
B:我也接完了
A:88
B:88
UDP,你閉著眼往一個框里扔球
1號球
2號球
3號球
即使2號沒進去,也不管了,繼續扔
4號球
....
不知樓主問的是tcp、udp,還是主要問socket
TCP不用說,最常見
在互聯網技術中,UDP常用在緩存讀取,保存;用在監控或終端上報;
常用dns服務,SNMP協議都是UDP協議的
如果是問socket的話,這麼講吧:
socket文件為同一台伺服器間的不同進程提供了一種網路通信的方式,通過文件就可以,而不需要通過物理網卡。
內核里sock和socket還是不一樣的兩個東西
問題太含糊,只能講這麼多了我很多年前剛從學校畢業的時候,和幾個人做過一個電子教學系統,是基於UDP的。
我們的系統使用場景是這樣,在一個電子教室里(lan, 那時internet還在撥號時代,根本承受不了我們的系統),老師在上課的時候,將自己的桌面實時廣播給所有學生,學生好像看視頻那樣,在自己的電腦上看老師廣播的內容。輪到學生做實驗的時候,學生的桌面又被廣播給老師,老師可以選擇查看某個學生的操作。
我們當時選擇UDP的原因很簡單,老師和學生用的都是普通台式機(奔騰+win98的樣子),用tcp的話,老師的機器很可能承受不了四五十個並發連接,而UDP是無連接的。另外,由於是實時廣播桌面,偶爾丟一個兩個包並不嚴重,並不需要tcp的可靠性。最怕就是對端udp重用了一下埠, 造成的串包(對端不想和我通信了,把socket 關了,然後新建了一個socket又把這個埠佔了,然後我又還傻呵呵的和這個socket通信,以為還是原來那個兄弟,有時候這種狀態要解出費勁死了。。)
其實我認為最關鍵的就是:
通信其實真的是個有狀態的事情。
傳輸卻是個無狀態的事情(努力收發吧)。
當使用udp做通信的時候,應用層在做通信,而內核認為自己在做傳輸。基層的理解小於了上層,上層要費姥姥勁兒才能把這個謬誤給糾正過來。
當你理解了上面說的這些的時候,你就可以明白,為什麼TCP的關閉是如此的複雜;你每少理解了其中一個要素,幾乎都會在udp通信中把虧給吃回來,所以我的建議是:
TCP做通信(尤其是點對點的,雙向通信的)
UDP做傳輸(push 流, 不可靠地push狀態更新, push app tips, 訂閱/發布者模式...,) 什麼是傳輸?最簡單的理解就是單向通信,單向推送,。。。無狀態如滔滔大江一去不復返,不用記得某滴水上次流到哪裡了,也不用管水最終流向何方(我有進入傻子模式見笑了)。
在通信領域,
TCP常用於IM,由於IM要求高抵達率,要求傳輸的可靠性,延時相較之下,不是那麼重要。
UDP常用語實時通信,要求超低延時。但是由於UDP的不可靠性,所以要求有額外的技術來補足這一缺點。
TCP:Transmission Control Protocol,傳輸控制協議是基於連接的協議,也就是說,在正式收發數據前,必須和對方建立可靠的連接。有延遲不可控的特點。
這類協議的特點是追求連接的可靠性,而造成了延遲的不可控性,超過2秒的延遲響應是常態,甚至幾十分鐘的延遲響應,而電信級的實時通信標準是400ms,而基於互聯網的實時通信需要另闢蹊徑,開創出新的傳輸解決方案。這又與應用場景相關了。發簡訊,延遲幾秒鐘送達,對使用者影響不大。
TCP協議封裝了消息的重傳機制,在丟包的情況下,採用TCP協議的應用程序幾乎無法優化這個重傳機制,來達到低時延的效果。特別是在移動互聯網路中,超過30%丟包時,TCP 的延時可以到幾十分鐘, 超過 50%丟包時,甚至很容易斷開。 在同樣丟包30%的鏈路上,UDP還可以傳輸數據,TCP就無法進行實時通信了。
UDP:User Data Protocol,用戶數據報協議,是與TCP相對應的協議。它是面向非連接的協議,它不與對方建立連接,而是直接就把數據包發送過去。 存在丟包、抖動、延遲的特徵。
聲網http://Agora.io採用 UDP 作為基礎傳輸協議。在設計低延時的實時通信服務時,UDP 表現要比 TCP 好得多。這是因為實時通信中,低時延比可靠性更重要。打電話,幾秒的延遲是不能忍受的。
我司基於UDP協議,對丟包的情況開發了各種演算法進行補償,一方面盡量保證和恢複數據的連續性。另外一方面,當某些數據包無法恢復時,會丟棄對應的音視頻數據包,而不會影響後續的實時通信服務。此外, 採用多機房部署,盡量縮短客戶端到機房的接入,並保證機房間的RTT小於60ms和400ms內丟包率小於1%,基於以上標準,進行篩選和部署伺服器,可以大大優化端到端的傳輸路徑,也大大降低時延的概率。
google的QUIC協議,也是基於UDP開發的協議。
如果有人感興趣的話,我下次再具體說說我們的演算法策略。
關於TCP和UDP的區別和概念上面都有人寫過了。我這裡寫一個UDP的應用。
在多人網路遊戲中,人物的移動可以用UDP來發。因為人物一直處於移動當中,會頻繁發出位置信息的包。由於發的比較頻繁,而且後面的位置信息會覆蓋掉前面的位置信息,所以丟不丟包不重要。就可以用UDP來發。每個UDP包的數據裡面加個時間戳,那麼進來的包你判斷下時間,如果是已經過期的包,就可以直接丟掉。這樣,即使udp包過來的順序不一樣都無所謂了。UDP選擇了速度而失去了可靠性,TCP選擇了可靠性而在速度上面做了些讓步。
我的主要領域是實時金融數據的處理,見過一些場景。
比如像外匯價格之類的數據,變化快,傳送延遲要特別低,偶爾丟一些數據也不怕,應為它變得實在是太快了。
但是有一些變化不多的數據,比如股票的收盤價,一天才一個,所以傳輸速度不重要,但一定要確保可靠性,不能丟。
支持UDP比較有名的軟體是real-logic/Aeron,一些英國做高頻交易的程序員做的。UDP和TCP的適用範圍是由它們各自的特性決定的。
UDP的特性是:數據報,無連接,簡單,不可靠,會丟包,會亂序(實際中遇到的主要是丟包)
TCP的特性是:流式,有連接,複雜,可靠,延遲較大、帶寬佔用較大(均是相對於UDP來說)
不同的應用場合會選擇不同的協議。以流媒體為例,一類是對實時性要求不高的音視頻點播應用(比如各大視頻網站),這類應用就多用TCP/HTTP,因為用戶可以忍受延時,可以進行緩衝,但不能忍受丟包導致的馬賽克。
另一類是對實時性要求很高的音視頻通信應用,比如視頻會議、視頻監控,這類應用用戶是無法忍受過高的延時的,相反,偶爾丟一下包卻無關大礙。而且,在這類應用中,基於UDP的組播技術也是經常用到的,因為它可以大大減輕伺服器和交換機的壓力。
不太同意陳碩的第一句話,在編程上,UDP比TCP簡單得多,因為它沒有建立連接的過程,而且是數據報方式,接收端不用像TCP那樣需要自己重組應用層的協議包。陳碩說UDP比TCP複雜,估計還是考慮到用UDP來實現可靠傳輸,如果是這樣,那就應該使用TCP。如果對可靠性要求不是那麼高,給UDP加上確認重傳也是比較簡單的事情(亂序問題我在實際中還未遇到過,也許是出現了未被觀察到)。
另外,SCTP是一個兼顧了UDP和TCP優點的協議,看它的特性是很吸引人的,不過我還沒在實際中還沒接觸過。頂樓是否忘記了天朝的DNS污染,DNS黙用使用就是UDP,就算使用國外的dns伺服器,域名的解析結果也會被改掉(在天朝的牆黑名單中的域名,如Facebook,youtube等),防火牆並沒有drop或reset客戶的dns數據包,只是修改了返回的數據。
說到使用數據加密方法過牆,這並不只適用於udp上,tcp也可以,很簡單的將數據做異或處理,在本機加密數據,國外的機子中解密,就足以翻牆。(天朝的牆說到?只能防下君子)
UDP現在應用的場景也不多了,早期的qq黙認就用udp,但現在基本tcp化了。還有現在的視頻播放,大部份也是tcp化了,主要原因是帶寬越來越高。
Udp相比tcp也就是少了啟動時三次握手,以及不進行數據包傳輸校驗,實際環境中udp丟包是很常見的,也有不少模型如vtcp,udpx等將udp模擬成tcp,進行數據包校驗,掉包重傳等,但依我看來做到極致,也就是一個tcp罷
我來回答UDP的另一個用途。 我們的晶元支持用UDP通信,由於CPU頻率的以及RAM的限制,容不下TCP的狀態機。 另外和晶元通信是嚴格的一問一答形式,包的長度絕對小於最大包長, 每次通信只需要獲取晶元的內部狀態,設置某些寄存器的值,因此不需要考慮先後到達的順序問題。
另外我非常贊同@張瑞的回答,配合TAP/TUN設備,使用UDP過牆我認為是最輕量的,這個場景下誕生了一堆開源VPN軟體,大家不妨關注一下ShadowVPN。我們甚至可以通過利用多個UDP轉發將不同路徑上的ISP出口帶寬全部轉到對端的TUN設備來提高過牆的總帶寬。
一般使用tcp,可靠性傳輸。但用udp也可以做的很完美,比如qq就是使用udp
最近看NAT穿透,發現一個據說比TCP連接效率高的reliable UDP庫,UDT
本地電信itv直播採用的是udp組播,加前向糾錯和網路qos保障。佔位下次來補充
推薦閱讀: