網路通信過程中,建立連接的本質是什麼?


謝邀。

網路通信建立連接的本質:告知彼此的第一個發送位元組的初始序列號,建立連接後對每一個發送的位元組都需要以初始序列號原點進行編號,需要對方來確認每一個位元組編號都已經成功接收,此乃建立連接的本質。

以大家都耳熟能詳的TCP來舉例,但是先強調一點,TCP 有兩個狀態位比較特殊,一個是SYN,一個是FIN,他們各佔一個位元組

A(初始序列號為0)--------TCP 連接--------(初始序列號為0)B

雙方初始序列號是由OS動態生成的,隨機的值一般每個TCP session都會有不一樣的初始序列號,佔四個位元組,為了便於描述,假定通信雙方的初始序列號都為0,A先發1000位元組的數據給B,發送成功之後釋放連接。

Step 1: A 發送TCP SYN 給B

Step 2: B 發送TCP SYN + ACK給A

Step 3: A發送ACK給B

完成建立連接,由於SYN佔用一個位元組,而ACK不佔用位元組,其實三次握手的本質是對SYN這個編號為0,佔用一個位元組的數據的雙向確認,此過程完成,彼此的真正數據的交換的編號為1,1。

Step 4: A 發送1000位元組給B,第一個位元組的編號為1,最後一個位元組編號為1000

Step 5: B發送一個包含ACK的確認號1001,意思是1001這個編號前的數據已經成功接收,如果還有數據要發送,請使用編號1001。

A主動發起釋放連接

Step 6: A發送包含FIN的單向釋放連接,編號1001

Step 7: B確認此釋放連接請求,ACK 1002

B發起單向釋放連接

Step 8: B發送包含FIN的單向釋放連接,編號1

Step 9: A確認此釋放連接請求,ACK 2,意思是FIN已經成功接收,連接可以釋放。

另外,TCP建立連接還會有MSS,Window Size,Scaling window ,SACK,SNACK,Security Authentication option等參數的協商,但是這些參數只是為了提高傳輸效率、增加TCP連接的安全性,避免沒有安全保護的TCP遭到第三方的偽造TCP Reset 攻擊。


謝邀,先簡單描述下。

建立連接這個詞,是從早期的電話系統中來的,那個時候,「建立連接」就真的是把你的電話和對方電話在電路上連起來。所以這個名詞就保留至今。

當然現在的電話網路,早就不需要為某個通信建立專門的電路連接了,單個通信鏈路支持多路通信復用。

從 TCP 角度來說,「連接」是個純粹概念性的東東。從開發者角度來看,假設我們的伺服器要跟隔壁老王(192.168.233.233)進行聯絡,基本的步驟大概是這樣的:

----伺服器(隔壁老王)的分割線------------------------

操作系統:我家有65535個郵箱,需要的來,先到先得。

應用1:int s = socket(AF_INET, SOCK_STREAM, 0);//給我開個賬號,類型是TCP/IP(AF_INET),通信方式是TCP(SOCK_STREAM)

操作系統:已開好,你的賬戶編號是9527(socket函數的返回值 s)

應用1:bind(s, 80); // 把80號郵箱(TCP埠號)分給我的9527賬號

操作系統:已經分好,以後發給80號郵箱的信都轉給你看。

應用:listen(s, ...); // 準備接受開房請求

----客戶端(192.168.222.222)的的分割線------------------------

伺服器操作暫時結束了,現在我們來看客戶端幹什麼。

操作系統:我有65535個郵箱,需要的來,先到先得。

應用2:int s = socket(AF_INET, SOCK_STREAM, 0);//給我開個賬號,類型是TCP/IP(AF_INET),通信方式是TCP(SOCK_STREAM)

操作系統:已開好,你的賬戶編號是1024(socket函數的返回值 s)

// 上面兩步,對伺服器和客戶端都沒區別

應用2:bind(s, 0); // 把隨便一個沒人用的郵箱分給我的1024賬號

操作系統:分好了,你的郵箱號是12306

應用2:connect(s, 192.168.233.233:80) // 讓我的12306號郵箱發的信只能到隔壁老王(192.168.233.233)的80號郵箱中。

操作系統:我去聯絡隔壁老王

操作系統:發一封信(網路數據包)到隔壁老王(192.168.233.233)家,上面寫我們家12306號郵箱想跟你家80號郵箱建立長期友好合作關係。

----現在回到隔壁老王家----------------------------------

操作系統:發現一封信?給80號郵箱的?好我轉過去

應用1:int s2 = accept(s,...); // 不斷查詢9527賬號,有沒有人想來開房?

操作系統:你鄰居老李(192.168.222.222:12306)想來開房,我已經給你分好了賬號是9528,以後你倆用這個賬號私下聯繫。

----又回到自家--------------------------------------------

操作系統:對方同意了

應用2:send(s, "你好,你叫什麼名字?"); // 發句話試試看

操作系統:發一封信(網路數據包)到隔壁老王(192.168.233.233)家的80號信箱,上面寫:「你好,你叫什麼名字?」

---隔壁老王-----------------------------------------------

操作系統:收到一封信,給80號郵箱的?拆開看看

操作系統:發信地址是鄰居老李(192.168.222.222:12306),我查查......已經給他們開好9528賬號了,直接轉過去吧。

應用1:string msg = recv(s2); // 從鄰居老李收到一條消息,內容是「你好,你叫什麼名字?」

這樣整個連接以及數據發送過就完整了。

------正經的分割線--------------------------------------

從上面的描寫可以看出來,所謂網路連接,並不存在物理上的動作。

  • 從伺服器角度講,新建一個連接代表著新建一個客戶端的記錄(地址:埠號),所有來自這裡的數據都交給創建連接的應用去處理。
  • 從客戶端角度講,新建一個連接代表著新建一個伺服器地址記錄(地址:埠號),所有從這個連接發出的數據,都只能發給連接指定的地址。
  • 而TCP是雙工的,所以連接建立後,兩端都是客戶端,也都是伺服器。

PS:這裡並沒有完整描述整個連接建立過程,比如DNS,ARP部分,有需要再寫吧。不過建議題主若想詳細了解,還是翻翻《TCP/IP詳解 卷一》更好,一個回答真的說不完。


連接的本質就是通信各方用一種共同認可的機制進行數據傳輸。

分層結構的出現就是為了大家協商出共同認可的機制,提供指導思想。TCP/IP就是這種指導思想的一種實現。


建立連接就是兩邊通過協議進入一個同步的狀態的意思。否則當你發包的時候對方可能沒準備好,結果就處理不了你這個數據了。


通信的本質就是信息的傳遞,把發送主體想要發送的信息傳遞給接收主體。建立連接的作用就是找到接受主體,並讓接受主體知道是誰想要給它傳遞信息。

建立連接的本質就是接頭(你得先找到你想要溝通的人),然後對暗號(雙方是否有意願進行溝通),對上了就開始交流了嘛!

例如你是我黨低級情報人員,有一個重大的情報要向組織報告,按照規定,你必須要把情報向你的上級情報人員彙報,於是你按照規定,來到了城中央的那間接頭的茶館,找到了接頭人茶館掌柜,並說出了接頭暗號,最樂觀的情況是對方認可了你的身份,然後雙方在安全順利的情況下交流了情報信息。

不太樂觀的情況:

1.你找到掌柜並對掌柜說出了暗號,但當時掌柜看到周圍有敵方官員在巡查,所以對你並不理會(對方主動關閉了連接,連接失敗).

2.你找到掌柜並對掌柜說出了暗號,掌柜認可了你的身份並準備進行交流,但在交流的時候,突然串出幾個官兵把掌柜帶走了,說他的茶館涉嫌偷稅漏稅,於是連接丟失(網路故障或者接受主體宕機)。


怎麼沒有人提OSI 7層模型?

其實在網路通信中建立連接的概念應該是OSI7層模型中至少四層建立連接吧,

1.物理層 MAC地址學習(可能包含虛擬的MAC地址)

2.數據鏈路層

3.網路層(說的最多的應該就是這個層面了TCP握手等等,貌似理論蠻多的)

4.是IP層么? 記不清了

一段收到一個數據包(原來叫報文)後每個層面識別,要麼丟棄,要麼拆分本層的包頭,往上層傳遞,最後到應用層面.

------------------------------------------------------

歡迎批評指正


網路雙方建立起對應的收髮狀態


就是發包以後對方確認,收到確認之後繼續發, 用確認的機制形成連接關係


電信號驅動有限狀態機的狀態變化


推薦閱讀:

python寫爬蟲軟體能不能爬flash(.swf)?
怎樣區分百兆網線和千兆網線?
入戶光纖放上PoE供電交換機,下端再放上不支持PoE供電的交換機,可以供電嗎?
VLAN 劃分與子網劃分聯繫與區別?
如何看待 10 月 21 日 美國遭到大規模 DDoS 攻擊並導致美國部分地區暫時「斷網」的事件?

TAG:互聯網 | 計算機網路 | TCPIP | 網路協議 |