為什麼要由TCP協議負責數據傳輸的可靠性?
可靠性傳輸為何不由網路層來完成呢?如果ip協議設計的在複雜一點,通過ICMP增加報文確認機制,同時增加超時重傳錯誤重傳等機制也是可以實現可靠性的吧?
如此設計的初衷是什麼?
看了下其他的答案,那些說「有其它的UDP之類的協議」,或者說「有些應用不需要可靠性」的,是將原因和結果搞反了。
事實上,是因為網路層沒有負責數據傳輸的可靠性,才出現了多種滿足不同需要的傳輸層協議。如果反過來想一想,如果網路層就可以保證可靠性,那何苦在傳輸層加那麼多複雜的協議呢?誰又不希望自己的下層協議是可靠的呢?
那麼真正的原因就是:網路層沒有辦法負責數據傳輸的可靠性!
這是由IP網路基於包交換(packet switch)的性質決定的。IP網路為了處理海量的數據,使用了極簡的方式:路由器只查看IP包的目標地址,在路由表中查找下一跳地址,然後把IP包發送出去。至於之前和之後的處理,路由器都不管。
保證可靠性一般有兩種方式:要麼建立一條專用的通道,就像傳統的電話網路;要麼針對一個連接預留出足夠的資源(緩存、throughput等),很多QoS是通過這樣解決的。
但以上兩種方式都違反了包交換的原則,會極大地增加路由器的複雜度和處理時間,使得這些不可能通用化。
所以,網路層只提供best effort服務,而由傳輸層來負責可靠性,把複雜的協議放在兩端,而不是網路上(fate sharing)。
因為有些場景下我們並不需要可靠性。
詳情見 http://tdc.iorc.depaul.edu/media/internet-design-philosophy.pdf
首先重複一下各位已經寫過的:
- 還有UDP呢,如果網路層只能提供可靠協議,那麼時延就成了問題。用UDP很多場景不需要可靠性但需要低時延
加一些:
- IP層協議棧是沒有「連接」這個概念的,是「按包轉發」,是無狀態的。IP層這樣的設計保證了IP對上對下的簡單。如果在IP層解決可靠傳輸,可以借用其他的協議,例如在IKE+IPsec協議上做一些增強。因為這兩個協議是有連接的。雖然他們是「沒有狀態的」。而實際上IPsec也有一些狀態,用來防止重放攻擊。
- 因為沒有連接,所以「擁塞控制」這個TCP層的重要功能就沒法做了。因為不同的「連接」走的路徑不同
- 因為沒有連接,所以ICMP也是無狀態的。如果IP層處理很多狀態,會讓ICMP搞得非常複雜
- IP層沒法管理連接建立和斷連
- 同一對(SIP,DIP)上的多個業務可能需要不同的可靠性和其他性能,如果「有連接」,那麼IP層必須為同一個(SIP,DIP)對建立多個context。管理困難
- IP的概念是「主機到主機」,但是IP控制則是「主機-路由器」,「主機-主機」,「路由器-路由器」三個模式。在IP層如果做基於連接的控制,會讓這個控制協議非常困難。
做協議的時候,要千萬注意「有狀態」和「無狀態」。前者是不用記錄context,不用管歷史。後者則需要從建立到刪除有一大套的協議和流程。
網路層適合做這些流程、協議、context嗎?顯然不合適。他負責的是「主機到主機」。TCP既然負責了「任務會話」,那麼「context」和「狀態」在他們之間協商、記錄、處理更合適。
網路層做無狀態,最合適。
當然可以由網路層完成,甚至可以由數據鏈路層完成。但是有這樣幾個問題:1.可靠性是以降低性能為代價的,強行在底層實現可靠性,那麼對可靠性要求不高而性能要求高的應用怎麼辦?2.網路分層的目的是讓每一層具備自己獨立的功能。數據鏈路層完成幀級別的傳輸;網路層完成網路級別的傳輸,傳輸層完成應用級別的傳輸。在每一層都不止有一種協議,他們遵循統一的封裝規則與上下層進行適配,通過這種協議族的組合實現不同的功能,適應不同的應用場景。因此,如果由網路層實現可靠性,那麼你不得不再實現一個不可靠的網路層協議,並且降低了協議族的靈活性,增加了複雜度。
先去思考一個問題:為什麼要有「分層」模型,不管是OSI7層還是TCP/IP4層
為的就是讓功能可以介面化、模塊化,可以「按需取用」,即插即用
按照你說的,把IP協議設計的在複雜一些,把可靠性加到IP協議裡面
而我這有一個不需要可靠性、但是需要低延遲的應用,比如視頻會議
那麼IP協議裡面關於可靠性的東西,對於我這個應用來說,就全是廢物,而我為了使用IP協議的基本功能,不得不帶著這些廢物,降低了性能
而目前的網路設計,我調用了IP協議,然後我考慮到視頻會議只需要基本的傳輸控制,對可靠性要求較低,於是放棄了可靠但是笨重的TCP,選擇了不可靠但是精簡的UDP,這樣就提升了性能。
好問題,以下是個人觀點。
確切的說,是TCP裡面應用了ARQ【1】方法,才達到了傳輸的可靠性。ARQ也曾經應用在短波通訊中,為鏈路層提供傳輸可靠性。所以理論上,也可以在網路層應用ARQ,以達到可靠傳輸。那為什麼不呢?為什麼現在常用的鏈路層也不提供可靠性傳輸(不算CRC)?
因為加上ARQ之後,鏈路變得「重」,影響了傳輸的速率。現在常用的物理層,與短波通訊相比,已經變得非常穩定可靠,數據鏈路層沒有必要加上ARQ。
不可靠的傳輸現在存在於網路層,多次轉發,代理,VPN,等等,對網路層的傳輸帶來了不確定性。那為了提高傳輸的可靠性,是在網路層加上ARQ還是在網路層之上的一層加上ARQ?結果你已經看到了,現在是在TCP裡面應用了ARQ方法。為什麼這麼做(其他答案已經提到了部分)?
1)為上層協議提供了靈活性,上層協議可以選擇可靠傳輸(TCP),也可以選擇不可靠傳輸(UDP),因為不同的應用場景對傳輸的可靠性和傳輸速率要求不一樣,如果在IP層做了可靠性,那麼應用層就沒得選了。
2)功能區分,網路層只關注數據傳輸,穩定性交給別的層去做,光是傳輸這個功能已經夠複雜了,你們忍心讓它再干別的嗎?同時這與之前在鏈路層添加ARQ類似,不穩定的物理層負責傳輸,再往上一層保證可靠性
3)儘管有MSS的存在,但是TCP Segment還是有可能在IP層做fragmentation。在TCP segment做確認重傳,帶來的額外負擔更小一些。
【1】Automatic repeat request
網路傳輸錯誤有兩種,一種是比特錯誤就是1變0和0變1,另一種是傳輸單元的重複缺失和亂序。前者各個層都有相應的檢糾錯碼。IP層因為速率考慮只是對IP頭做檢查。後者的解決辦法就是編號。
網路層無法實現可靠性傳輸,因為網路層無法應對第二種傳輸錯誤:分組的重複缺失以及亂序。網路層的傳輸對象是分組,但是一個應用層的消息會被切成多個分組傳輸。就算網路層保證了單個分組的可靠傳輸也無法保證多個包組合起來是可靠的。因為分組可能出現亂序重複缺失,解決這些問題的方法就是給分組編號。但是按照現在的網路協議分層,網路層連完整的消息長什麼樣都不知道它怎麼編號?當然你說就讓網路層拿到完整的消息,讓網路層切片編號再可靠性傳輸,那不就是把網路層和傳輸層變成一個層嗎。
我看問題評論有人問為什麼不讓物理層和數據鏈路層來實現可靠性傳輸。跟上面的道理一樣,數據鏈路層哪怕保證了每一幀是可靠的,它也無法保證你的消息是可靠的,因為一個應用層消息給下來會被切片,數據鏈路層無法解決幀的重複缺失亂序。只有傳輸層和應用層擁有消息的完整信息,可以對它切片編號,所以只有傳輸層和應用層才能實現可靠性傳輸。傳輸層的TCP只是給應用層提供了一種通用的可靠傳輸協議,至於應用層想自己來還是直接用TCP那就看開發者自己的選擇了。QQ好像就是UDP+應用層協議來保證可靠和加密傳輸的。
我覺得應該這樣理解,網路的設計是分層的,每一層只解決一個核心問題,這也是UNIX系統的一個核心理念。IP網路層解決一個點找到另一個點的問題; 用TCP解決的兩個點之間可靠通信的問題,tcpip最初實現在UNIX環境下,這是符合當初的操作系統設計原則的做法。
正好在看計算機網路的書。有個例子挺好
這裡陷入了一個無限循環的狀況。因為網路(這裡理解為信道)本身無法保證數據可靠送達,所以題主說的什麼差錯重傳,在這裡就陷入了這樣的循環。
另外,如果網路層負責東西太多,就會增加時延,不利於快速找到目標主機。所以每一層都做好本職工作是最好的,檢驗機制可以交給運輸層和數據鏈路層來搞定。至於網路層,盡最大努力找到下一個目標地址並且迅速轉發出去才是最重要的。有些協議就像送報紙,不小心送錯了,也沒關係,再送一份給客戶就是了,損失不大,甚至很多客戶你萬一不小心沒送到,也沒關係。
而有些就像銀行送票據,丟了可是大買賣!就要小心確認。可想而知,如果送報紙和送票據混在一起,那麼每送一份東西,都要小心翼翼,效率也非常低。。。
視頻傳輸也是,你上網看一部電影,不小心卡了一下(就一閃而過),你基本不會返回幾秒重新看,而是繼續看下去。這樣也顯然用不到類似於TCP的穩妥。—————再簡單比喻,網路傳輸跟快遞物流很像,一個快遞員當然也可以負責很多事情,比如:從收件到運輸,再到另一個客戶手中,都由一個人全程完成。
現實中,顯然沒有這麼干,有的專門收件,有的專門運輸,有的客服,有的運營,不同層次的管理協議才能最有效率。
快遞物流的每個環節,都有專門人員負責,更專業分工,協議也是如此。
再假設,如果每個快遞員都全職了(從收件到派件全包攬),那麼,雙11期間,有多少億的包裹,就有多少個快遞員在各省市之間送快遞,交通道路都吃不消。顯然,這樣相比由一些人專門開運輸車運送,效率低很多。我覺得最好最簡單的解釋就是網路講究分而治之。 要把一個大的功能模塊打碎成許多個原子的小積木,允許使用者自行根據需要組合拓展。
IP協議是逐跳的,核心就是提供一個簡單強壯的無中心網路。在這個基礎上再添加上tcp的可靠性支持,不就是相當於打包了網路層和一個砍掉UDP的傳輸層。這種方案的優勢在哪呢?
可靠性也不一定就要做在傳輸層,甚至我們根本就不需要可靠性都是有可能的。我覺得udp的存在不僅僅是提供了一個無連接不可靠的傳輸,還包括給予了應用層自定義傳輸邏輯的能力。
不管是五層模型還是四層模型的設計,都是基於簡單原則設計的,即每一層只做自己的一件事
你想怎麼加進ip里去?可選還是必選?可選的話不就是tcp嗎?必選的話,怎麼使用udp?而且重傳機制本來就是與傳輸邏輯上相聯繫,你非說設計一個layer實現兩個layer的功能,可我覺得他本質上還是兩個layer,只是認為劃分的話更容易認知。分層的思想或許更利於開發,每層只負責部分功能,職責劃得細,排錯就好找目標。哪層出錯就找哪。分層分多了,頂層到底層的工作量就會提高,層與層之間協同就會變得麻煩。
謝邀,設計遵守的高內聚,低耦合原則沒有體會透徹,你永遠不知道未來會有什麼需求,讓一個協議實現所有的事情,只會讓其臃腫,華為的板間傳輸協議每秒7G,既不是TCP,也不是UDP,需求是多變的,我認為軟體設計第一原則就是考慮多變的需求!
問為什麼要,建議先想一個問題:如果不這樣呢?
如果IP層就保證了可靠傳輸,那UDP怎麼實現呢?沒了UDP,如果現在已有的代碼UDP傳輸的地方換成TCP,會有什麼影響。
現有的網路分層結構都是經歷了長久實戰考驗的,要去對它為什麼這樣設計做深入了解,那需要看的就很多了。
建議去看一下《計算機網路》,特南鮑姆寫的那本,很詳細,看了之後心裡大概能有個底了。tcp只是一種可選協議,同層的還有udp。 如果你把網際層設計得tcp化了,那udp該怎麼實現呢? 目前還有很多服務都是基於udp這種快速但不可靠的傳輸的。所以在上層再做區分更好。
@王邈 的答案已經解答,補充一下可以看看udp
當然可以啊
但是在我們的世界有些東西比效率的重要度更高,那就是規則和維護OSI七層協議是標準,你可以不按這個來,而且按你說的來,只要的用戶面更大成為事實上的標準。就像TCP/IP的五層結構 。
所謂標準就是大多數,你不按標準就不能與其他人信息互通,因為介面不同
至於為什麼設計成IP層傳輸不可靠報文,是因為他們設計了TCP層來完成這個功能每一層有每一層的作用,如果想讓網路層控制保證傳輸可靠或者不可靠,一樣需要加欄位加流程,那就新網路層=傳統網路層+傳輸層,不是一個意思?然後網路層的每一個協議都要區分可靠和不可靠兩種情況,不累嗎
IP層只是負責定址。
TCP/UDP是負責報文的傳輸。如果他們不負責傳輸的可靠性,那麼就可以不要他們了。
網路層為什麼一定要負責可靠性?你這樣會讓UDP失業的。
而且網路層就沒有校驗了嗎?
推薦閱讀:
※自學web前端真的很難找到工作嘛?
※任何情況下的數據傳輸都需要建立連接為什麼是錯的?
※默認網關設為192.168.0.0代表啥意思?
※如何系統的學習計算機網路相關知識?
※在tcp鏈接的釋放過程中,由於存在TIME-WAIT階段,會影響其他程序在該埠建立tcp連接嗎?