tcp 的可靠性到底指的是什麼?

問題的產生來自於一次面試。

當時面試官提了一個這樣的問題:
如何保證數據在tcp傳輸過程中的可靠性?換句話說,就是,怎麼保證數據在傳輸過程中不被修改?

當時,我一通胡扯,說tcp是可靠傳輸,所以不存在這樣的問題。 最後問了面試官,他們是怎麼處理這種問題?

親切的面試官給了一種簡單的方案:
在每個 tcp 段的數據部分首部,額外使用若干個位元組,用於標示這次要發送的數據的長度,在接收端,通過檢測這若干個位元組以及數據的長度,來判斷此次通信是否被修改。

基於這次面試,我又開始回顧之前所學的tcp/udp等內容,發現大部分博客和教材都只是說了 tcp 是可靠傳輸,但是仍然沒有指明tcp的可靠性到底指的是什麼?

1)保證每個tcp段(segment)都能成功的被接收端接收到嗎?只要成功接收,而不管中途有沒有被修改?

2)還是也要保證每個段的內容,在傳輸過程中不被修改,如果修改過,那麼在接收端會選擇拋棄該段?


面試官混淆了 Error Detection 和 Reliable Transmission 的概念。

面試官說的校驗和是一種錯誤檢查的技術。是靠頭部一個 16 bit 的 checksum 完成的。

所謂可靠傳輸是指在通訊時常見的丟包,亂序的條件下依然可以保障數據被依序接受,中間不丟數據。是靠序列號,滑動收發窗口, 接收方ACK 和 SACK, 發送方重傳等機制保障的。

說 Reliable Transmission 需要 Error Detection 保障還說的通,但僅說 Error Detection 代表不了 Reliable Transmission。


TCP的可靠性應該是相對於UDP不可靠傳輸來說的,因為UDP提供的是不可靠的數據報服務,不保證數據報能到達接收端,可能會有丟失;另外處於傳輸層之下的IP層也是不可靠的,僅提供儘力而為的端到端數據傳輸服務(best-effort delivery service),不作任何保證。所以TCP的可靠性是指基於不可靠的IP層在傳輸層提供可靠的數據傳輸服務,主要是指傳輸數據不會損壞或丟失,而且所有數據都是按照發送順序進行傳送。
實現TCP的可靠傳輸有以下機制:
1,校驗和(校驗數據是否損壞);
2,定時器(分組丟失則重傳);
3,序號(用於檢測丟失的分組和冗餘的分組);
4,確認(接收方告知發送方正確接收分組以及期望的下一個分組);
5,否定確認(接收方通知發送方未被正確接收的分組);
6,窗口和流水線(用於增加信道的吞吐量)。
至於數據是否在中途被修改或者被竊聽,這應該是屬於安全性問題。提高安全性最根本的辦法就是加密數據,比如遠程登錄用ssh而非telnet。


確保數據在傳輸中不被篡改,是確保數據的完整性

通常來說方案是數字簽名

在每個 tcp 段的數據部分首部,額外使用若干個位元組,用於標示這次要發送的數據的長度,在接收端,通過檢測這若干個位元組以及數據的長度,來判斷此次通信是否被修改。

這個方案基本聊勝於無

雖然TCP協議也有校驗和來確保包的完整性,但是這個校驗和不能防止惡意篡改,而是應對網路傳輸中的干擾信號等。

然後又發現很多人沒有分清楚數據傳輸安全性和數據完整性之間的區別。
確保數據完整性只需要數字簽名,不需要對整個數據進行加密,數字簽名的原理是對數據的摘要信息(SHA、MD5)進行非對稱加密來校驗數據的完整性。用途其實非常廣泛,例如操作系統自動更新的文件,驅動程序,這些都用數字簽名來確保完整性,卻不需要用什麼安全傳輸協議來傳輸


防意外丟失和防蓄意攻擊是兩碼事。

TCP本身主要是針對前者設計的,也就是說傳輸過程中受到干擾,錯了一兩位數據、丟了一兩個包之類的情況,它能比較好地應對,也就是題主你所謂的可靠
但是,這並不能避免你的明文數據被嗅探或被篡改。網路上的各種第三方設備隨時可能截獲數據包查看內容,或者偽造數據包——checksum這種校驗非常弱,規則都是透明的,同時篡改數據內容和校驗數即可輕而易舉地狸貓換太子。也就是我們所謂的不安全

應對的辦法就是加密。沒有密鑰的第三方即使拿到數據包也無法還原成有意義的內容,更無法修改替換。還有一個很重要的是身份認證,防止雙方從最開始就被中間人兩頭騙。SSL/TLS是一個比較成熟通用的解決方案。


題主描述中面試官給出的方案有點萌。


TCP的可靠性非常脆弱,只要有中間人人為的篡改數據,同時對篡改的數據重新計算checksum,到達目的地TCP層很顯然檢測不出數據已經被篡改了,會提交給application,如果application沒有自己的糾錯功能,那目的地application就被篡改的數據欺騙了!

既然TCP如此脆弱,為何我們還稱之為可靠傳輸?那還要追溯TCP的歷史,TCP/IP本來是一個美國區域網的標準,用於區域網內主機之間的通信協議,由於物理鏈路安全可控,沒有第三方的人為破壞,所以TCP checksum可以一定程度上檢測到,由於信號突變而產生的數據錯誤。再加上TCP對傳輸的數據有確認機制,所以在這個大前提下,我們一直稱TCP是一種可靠的傳輸機制。

但現在的TCP暴露於開放的互聯網世界,在傳輸過程中要經過很多設備,只要有人為篡改數據,但通過精心數據調整,checksum卻和沒有篡改之前是一樣的,所以說TCP的可靠性非常脆弱!

那難道就沒有辦法了嗎?有的!TCP有一個option 19,Authentication Option,MD5 Hash,其工作原理如下:

以TCP報文數據 + Pre-Shared密碼做為共同輸入參數,生成一個MD5 Hash(MAC:Message Authentication Code),這個Hash有三個特點:

1)唯一性

原始TCP報文數據對應唯一一個MAC

2)不可逆

根據MAC無法推導出原始的報文,也無法推導出共享密碼

3)確認數據來源於真正的源

由於pre-shared password 只有TCP源與目的端知道,如果目的端計算出相同的MAC,則一方面證明數據沒有被篡改,另一方面也確認數據來源於真正的源

基於以上三點,TCP option 19 可以幫助TCP完成數據可靠傳輸的數據校驗功能,以及數據來源的合法性檢查。

但MD5由於有過被成功破解的例子,所以其安全性保證受到了質疑,於是TCP又開發了一個新的選項:option 29 ,Security Option,即採用SHA Hash,目前SHA Hash作為一種安全的哈希函數,目前還沒有被破解的先例,SHA已成為最流行的、提供數據完整性(Data Integrity)保護的哈希函數。

有了TCP Option 29 的保護,可以很自信地說,TCP是一種可靠的傳輸層協議。


這裡有一個邏輯錯誤:可靠傳輸 === 數據安全。


&> 在每個 tcp 段的數據部分首部,額外使用若干個位元組,用於標示這次要發送的數據的長度,在接收端,通過檢測這若干個位元組以及數據的長度,來判斷此次通信是否被修改。

這玩意不就是 Payload Length 么?Window Size 不也可以么?為毛還要自己搞個欄位?


可靠性和完整性不一樣。面試官不準確。


這個問題和面試官對問題的補充說明是兩個東西。問題是可靠性,但補充說明又是講的完整性。換言之面試官自己就是糊塗的。
可靠性其實簡單,就是握手,序列號,重傳。至於完整性,那是安全方面的東西,我的認識里不是TCP本身要解決的問題。


沒區分reliability和security。


可靠性不僅僅指數據在傳輸過程中不被修改,還指數據成功抵達、有序投遞、數據不重複。

1,數據被篡改導致對端接收進行checksun校驗失敗後,會丟棄此包,發送端重傳;
2,數據傳輸過程丟包或延遲,發送端重傳;
3,發送端給每個報文標記了SeqN,接收端根據此欄位排序,保證有序;
4,因延遲,重複抵達的數據會被接收端拋棄。

前段時間我恰好寫了篇關於tcp的文章,想弄明白的話,讀一下就明白了。如若還有不明白的地方,歡迎私信,一塊探討、學習。
文章傳送門:http://zhuanlan.zhihu.com/p/21957820

祝題主找工作成功!


tcp的可靠是基於握手機制下的通信雙方的目的與源都可知,相對udp是不可靠的,因為不確認目的是否可達就發了,我只發就行了,收不收的到就不關我的事了


講真,題主能不能說說這是哪家公司?給個名字,好讓別人少去踩坑?

這面試官給的解決方案,顯然既解決不了可靠性,也解決不了安全性。加個長度校驗就想保證不被篡改??未免太tm瞧不起人了


面試官這個就扯淡了,我知道你的校驗方法,我難道不能改你數據的時候連你校驗的部分一起改么。。。

防止數據傳輸過程中的隨機出錯和防止數據被修改不是一個層面上的東西,TCP在前者上做了一些工作,後者是安全領域搞的事情,通信加密,防中間人等等,跟TCP本身關係不大。。。死摳到底什麼叫可靠傳輸就沒意思了。。。


1.確認和重傳機制
2.數據校驗

3.數據合理分片和排序

4.流量控制
5.擁塞控制
我面試就是這麼答的,再細問就說說如何確認和重傳如何進行擁塞控制等等。。。最近也在找工作。。


TCP可靠性,在教科書中的描述主要是對數據的比特無差錯,不重不漏,且最終接收方能按序交付上層。當然為了儘可能避免發生丟包,附帶了流量控制和擁塞控制的功能。一句話,TCP可靠性主要針對傳輸過程中的差錯。並沒有對數據被竊取等安全性能做特別考慮。

我看的教材是計算機網路,自頂向下設計
其中關於傳輸安全性能的考量,是放在socket層面。
應用層把數據傳給SSL,SSL加密之後給套接字,套接字交給傳輸層。
如果放在七層網路模型來看。SSL其實充當了表示層的作用。


TCP的可靠性和安全性完全兩碼事,這個面試官都搞錯了,可靠性是指丟包會重傳,傳輸過程不被修改才是安全性,這個問題就大了,http協議里有用,但是
放到原始TCP套接字上未免大材小用。面試官問得應該是如何避免一幀數據有部分丟失,用TLV的方式非常原始,json的自我校驗就可以解決這個問題。


1.完整性檢查
tcp協議header中有個checksum,用來檢驗接收到的數據的完整性,保證沒被篡改。接收端根據tcp data計算checksum,如果與header中的checksum一致則接受並回復ack。
2.
tcp要求必須被對端接收並收到對端回復的ack才能進行後續的數據傳輸,否則就進行這個tcp數據的重傳,這樣就保證盡最大可能將數據送達。當然協議中有重傳上限的設置。
這就是為什麼說tcp是best effort,udp是try。


自己定義的數據傳輸協議加個magic num


面試官的確說錯了
可靠性 不(等於或包含) (防篡改 或 防重放 或 防泄密)
簡單的說,TCP有ACK機制保障端到端的可靠性,這個可靠性指一個tcp段,如果發送失敗,是會重傳的。tcp上層機制,例如應用軟體(通常)無需承擔確保傳輸可靠性的。

而防篡改、防重放、防泄密,這些安全性保障,通常是需要由 IPSec 或 TLS 等機制配合密鑰(如簡單的口令或更複雜的PKI體系)來提供。


推薦閱讀:

ospf處在哪個tcp/ip的層次,是不是傳輸層,網上說tcp/ip不夠嚴謹,那麼對於osi呢?
IP報文的目的IP地址是私有IP地址,網路層如何處理的?
智能DNS解析?
nginx不是使用epoll么? epoll貌似是同步的吧! 那nginx的非同步非阻塞到底非同步在哪裡?

TAG:計算機網路 | TCPIP | TCP | 網路工程 | 網路協議 |