tcp連接的問題?

根據osi七層模型,客戶端從應用層封裝數據,形成數據包,表示層進行加密數據格式及加密,傳輸層把資料庫包放在幀裡面進行傳輸。那每一層都有每一層的功能,我的理解是,客戶端自上而下,每一層協議進行加工和傳遞,應用層處理完了,把根據協議內容處理的結果給表示層,表示層之類的處理完了,再把應用層的結果加上表示層的結果一起往下傳,以此類推,在最底層的時候就有上面6層一起傳來的協議,再把這個整體傳到伺服器,伺服器再自下而上的根據不同的層次協議進行不同的處理。這是我對網路編程的理解,第一我不知道我理解出錯了嗎?第二個,在我的這個理解基礎上我不是很懂tcp連接具體概念是什麼,tcp不是一個把資料庫包放進幀的一個協議嗎?為什麼要進行三次握手,三次握手的本質是不是從傳輸層開始,傳送確定的信息,然後也是一層層往下傳遞不同層的協議到達底層,再傳給伺服器,伺服器再解析?


每次看到類似的問題,都會回想到往昔在東大工程院聽顧冠群教授《區域網》第一節課,介紹的OSI參考模型,聽得懵懵懂懂,我不斷問自己一個問題,為何一定要有那麼多的分層?既然你應用程序需要通信,為何要麻煩別人?能否就分為兩層:硬體層、軟體層?

確實可以的,我剛工作的時候確實也用兩層的模型實現過通信,將硬體驅動成HDLC介面,然後直接往介面寫入數據,在電纜的另外接收端,讀取數據。

接下來的問題是,如何知道發送的數據接收端成功接收?既然學過了TCP協議,於是借鑒了TCP將每個位元組編號的方法,比如發送一個位元組,將其編號為1000,對端收到會回復一個確認號1001,表示編號為1000的位元組數據成功接收。

一下子感覺TCP協議欄位好像很有道理…

還有,既然要位元組編號,接收端如何知道發送端的編號從哪裡開始?是1、100、1000還是10000,這個起始編號接收端需要預先知道,於是又借鑒了序列號TCP同步過程,這個過程就是大名鼎鼎的TCP三次同步握手!

至於為何是三次,而不是二次或四次,請參考這個答案:https://www.zhihu.com/question/24853633/answer/115173386

三次同步握手,其實不是真正傳輸我的數據,而是在兩端就初始位元組編號交換一下意見,三次消息交換,雙方達成了共識,知道了彼此的初始序列號,這個過程完成,我用一個結構體保存狀態為:Established

接下來,開始了數據的傳輸,對方也很快確認了,一端發,對端確認,玩得很歡樂…

於是我發位元組2000-3000,可是對端遲遲沒有動靜,難道就這樣一直等下去?於是我查看了一下,原來電纜鬆動了,物理連接斷,數據丟了。

既然數據丟了,發送端等到太陽從西邊出來也等不到對端的確認。

於是又翻書看TCP,裡面看到超時重傳定時器,我也給自己的位元組數據啟動一個鬧鐘(Timer),一旦鬧鐘響,就觸發一段重傳的代碼,將數據重新發送出去,發完再啟動鬧鐘,然後靜靜的等對方的確認。如果連續嘗試多次,依然沒有收到對端的確認,將直接報告連接斷並退出程序。

但如果一旦網路恢復(重連電纜),數據又可以繼續傳輸,而不會因為丟一個包而韁在哪裡,造成通信死鎖。

還需要用結構體緩存重傳數據超時重傳的次數等等,這些結構體都需要記憶,只要連接在,結構體就在。

等我把這個程序寫好,突然發現,這些代碼不正是TCP完成的嗎?人家TCP已經通過Socket介面提供給我了,而我卻要捨近求遠。

於是我的程序不直接與硬體勾搭,而是用TCP/IP與其勾搭,我的程序與TCP/IP勾搭,其中:

硬體 — IP —TCP —我的程序

其中TCP/IP作為系統進程位於操作系統內核,兩個協議早就水乳交融了,我只要讓硬體給IP提供標準的發送/接收介面函數該介面函數恰恰就是原來提供給我的程序調用的,現在讓IP去調用

我的程序只需要調用標準的socket函數,提供一些參數即可,比如對端的IP、埠號,讓TCP先建立連接,等狀態為Established,我就可以發送數據了,應用程序還需要給位元組數據編號哇?不需要,由TCP來做!還需要應用程序重傳數據哇?不需要,由TCP來做!

如果宏觀地看,應用程序把「TCP/IP」看成自己的代理,去和本地的硬體搭訕、並最終與對端完成通信,至於可靠傳輸實現的細節,那是代理的事,其實應用程序無需關心。

比如想去註冊公司,如果自己跑工商、稅務、銀行,至少要10多次,手續特別煩瑣,什麼企業核名、註冊地址、公司章程、法人一證通、企業銀行賬戶、核定稅種、購買發票,需要知道哪個流程要哪些材料,這太痛苦了。

而代理可以全程完成以上的任務,只需要提供一些必要的材料、手續費,就可以等著代理完成所有的手續,專業的事讓專業的人做效率最高。

既然分層,則需要在原始的數據頭部添加每層的協議頭,底層在最外,以此類推,應用層被包裹在最裡面,這就是封裝(Encapsulation)。

而每層的協議頭,其目的為何?是為了接收端對應層(Peer Layer)來提取信息的,這就是解封裝(Decapsulation)。

但不是每層僅僅做封裝/接封裝,有的層還需要對應用層數據保存狀態,比如TCP,並為了更好地服務應用程序,背後做了大量工作,建立連接、超時重傳、排序、流量控制、釋放連接、出錯重置連接等。

TCP攬下了應用程序的所有粗活、累活,所以TCP是一個不平凡的協議!

關於分層的概念,live有詳細的講解:https://www.zhihu.com/lives/897123723914649600


分層模型兩個核心:

上下層間服務
對等層間協商/業務

你剛剛表達的是第一個核心思想

你想問的是第二個部分:對等層

第一個要注意的是,對等的對端是誰。

主機a和b間的通信,並不是所有的對端都是a和b。以tcp/ip/乙太網為例。


a的物理層對端是第一跳交換機
鏈路層的對端是第一跳路由器(網關)
ip層以上對端才是b

但是,從a的ip到b的ip之間是一個不能保證的網路,不保證送達,不保證順序不保證不重複。

但是應用需要可靠的服務怎麼辦呢?

tcp本端和對端間進行各種控制,通過兩端互相通知,互相配合,達到可靠服務。比如,a發包的時候打上標記,b收到以後告訴a,我收到了,你可以繼續發後面的數據了……

你看,經過tcp層的兩端配合,可以為上層提供可靠的服務。


OSI七層模型是一個僅停留在理論的模型,而現實網路中採用的是TCP/IP協議簇. TCP三次握手建立連接後,雙方都清楚1)對方發過來的每一個TCP包payload序號是多少,是新包或者重傳2)已端發送出去的TCP包對方接收到了多少


以我的理解回答一下。我覺得這是現在網路教材一個容易誤導人的地方(但準確地說也不能算錯)。就是ISO/OSI協議是7層:應用層、表示層、會話層、傳輸層、網路層、數據鏈路層和物理層。但實際上常用的TCP/IP協議是4層:應用層、會話/傳輸層、網路層、數據鏈路層和物理層。其中UDP協議可以看作傳輸層協議,TCP則是會話層和傳輸層合併的協議。應用程序建立TCP連接之後,就已經進入會話,直到斷開。關於三次握手,你的理解大致是對的。


可以讀讀我公眾號的這篇文章:面試題23解析-Java Socket與TCP/IP協議棧 。


推薦閱讀:

前途未卜的准程序員,吃過苦頭有智慧的或者過來人前輩大牛有什麼樣的忠告給當局者?
金融工程的新生怎麼選購筆記本電腦?
浙大的計算機和電氣從就業來看選哪個好?
知乎上最牛的程序員有辦法知道任意匿名用戶是誰嗎?
如果世界上只剩下五種編程語言,你希望是哪五個?為什麼?

TAG:程序員 | 編程 | Java | 計算機科學 | TCPIP |