TCP連接中a連b和b連a是一碼事嗎?

有人問我,TCP連接中,一台內網電腦通過路由器訪問外網伺服器,那伺服器可不可以通過這個連接直接訪問到內網電腦?我只知道要做NAT穿透,但是人家跟我說都拿到連接了,直接連不就行了。。。總感覺雖然是我連接了你,但你要用我這個我連你的連接,應該是不行吧。。。唉:-(網路那塊學的太差,有沒有來個解釋的清楚點的,從底層協議剖析剖析?


本故事純屬虛構,如有雷同,純屬巧合。

古時有一情國,為了保護臣民不為外敵侵擾,建了城牆,城內的子民無事不得外出城外,如果出城,則需要獲得特別通行證,通行證有效期為5天,五天之內可以自由出入,每張通行證都有一個唯一的序列號,避免混淆。

城內的一名字叫小明的男子,最近適逢情人節,犯了相思病,因為自己的夢中情人小美嫁人了,嫁了一個富二代,小明每逢佳節倍思小美,茶飯不思,卧床不起,急壞了父母大人,於是差人去城外請神醫華佗前來醫治,小明的家人在門衛處獲得了特別通行證,序列號為201702140520,於是帶著這個通行證出城了,很快就找到了華佗,由於擁有特別通行證,並且在有效期內,所以順利進城,華佗查看了小明的病情,對小明耳語了一番,小明聽了一驚,旋即從床上坐起,對華佗說:多謝神醫,我的病好了…

以上故事裡的序列號就是NAT映射表裡的TCP埠號,城裡的人出去,自然有序列號,所以雙向通行無障礙。

如果這個序列號在NAT表裡不存在,意味著通行證過期了(五分鐘超時刪除),或序列號本來就是非法的(門衛從來沒有頒發過這個序列號),城外的人(外部主機)會拒絕進入城內。

但如果序列號是合法的,意味著在有效期內,且門衛頒發過,那城外的伺服器可否連接城內的主機呢?

如果城內的主機使用自己的初始埠號2000監聽連接(即允許外部連接),這個埠號是主機A連接伺服器B的埠號,主機A和B的連接已經關閉,伺服器B可以主動連接主機A。

總結一下:
A主動連接B,是在NAT表生成一個允許外部伺服器B向內連接的表相,如果A可以使用同一個埠號監聽外部連接,則伺服器B可以主動連接A。


首先我們來看一下 《TCP/IP詳解 卷一》 中關於TCP的服務的介紹。

TCP提供一種面向連接的,可靠的位元組流服務。
面向連接意味著兩個使用TCP的應用(通常是一個客戶和一個伺服器)在彼此交換數據之前必須先建立一個TCP連接。這一過程與打電話很相似…………

題主可以這樣想:你打電話給某人,電話接通( TCP 三次握手完成),然後你們兩個人就可以隨意說話了。

而不是題主先打給某人那麼只有題主能說話,某人只能聽,如果某人想說話還需要另一部電話機打給題主。


更細節的情況是這樣的:

假設:

題主通過瀏覽器訪問知乎,TCP 三次握手已經完成。

瀏覽器發出一個包 :[ 目標:知乎伺服器 IP , 80 埠。來源:題主機器內網 IP, 埠 a 。]

包很快就送到路由器。路由器查詢路由器里的 NAT 表可以得到:

題主機器內網IP ,埠 a &<----&> 路由器公網IP ,埠 b

路由器把包修改成:[ 目標:知乎伺服器 IP , 80 埠。來源:路由器公網 IP, 埠 b 。]

包來到知乎伺服器。伺服器一番處理後返回包 :[ 目標:路由器公網 IP ,埠 b 。來源:知乎伺服器 IP , 80 埠。]

包很快來到題主的路由器上,路由器再次查詢路由器里的 NAT 表可以得到:

路由器公網IP ,埠 b &<----&> 題主機器 IP ,埠 a

路由器把包修改成:[ 目標:題主機器內網 IP , a 埠。來源:知乎伺服器 IP, 埠 80 。]

這樣題主的機器就收到了知乎伺服器發出包。


而平時說的 「做 NAT 穿透」就是手動在路由器上 NAT 表上添加規則

路由器公網IP ,埠 b &<----&> 題主機器內網 IP ,埠 a

這樣外網的機器就可以直接通過公網 IP 埠 b 與 題主的機器建立連接。


如果沒有「做 NAT 穿透」,題主的機器主動向外網的機器發起 TCP 連接時路由器會自動在 NAT 表裡寫入規則。但是外網的機器不能主動連接題主的機器,因為路由器 NAT 表裡沒有相關規則,而外網的機器也沒有辦法告訴路由器:包應該送到內網哪個機器的哪個埠。

不知道這樣說題主明白嗎?


你從家裡可以找到火車站,因為火車站的位置大家都知道,你每走到一個路口都知道接下來怎麼去火車站。
但是一個人從火車站找你就不容易了,因為發出來的包ip地址可能只精確到小區,路上最多只能知道你的小區怎麼走,你住哪個單元幾零幾是不知道的,你的小區可能只對應一個ip地址,nat就是把你小區的某個口直接映射到你的家門,這樣找到你的小區就相當於去了你的家。


「我連接了你,但你要用我這個我連你的連接」這句話可行,這就是NAT穿透中的「打洞」。NAT穿透的全過程都是通過這個埠來傳輸數據的。舉個例子吧,比如你是A,內網主機B設有HTTP伺服器,你要讓外網的主機C通過域名訪問你內網主機B的80埠,但是NAT網關沒有開放任何埠,這時候怎麼辦呢?A可以通過內網穿透軟體主動連接一個另外伺服器D(當然這個伺服器要有公網IP),NAT網關會自動建立A與D的TCP通道,埠隨機,這條通道就是一個「洞」。要讓B能夠訪問C的80埠,你可以把域名設為D的IP地址,然後D就會通過與A的這個「洞」,讓A代理C先去訪問B,然後再把數據遞給B,最後再遞給C。全過程大概就是這樣的。現在什麼蒲公英內網穿透路由器就是這個原理。表達能力有限,希望能幫到您!另外可樓主以去找一下NAPT的資料。


建立連接後是一回事,建立之前不是一回事。你打電話給110和110打電話給你在打通之後是一回事,就是兩個人聊天。但是一般你知道110的電話號碼,你的電話號碼110不一定知道。


記得有個問題可以解答你的疑惑,從三月到12月,經過了9個月,而從12月到三月,才經過3個月?


如果只是看tcp層面,鏈接建立之後,誰主動誰被動其實沒啥區別。
但是,從題主的問題描述來看,兩種說法差別很大。原因在於,網路的設計是分層的。不同層面解決完全不同的問題,這裡的不同在於三層IP路由方式不同。a可以路由到b,但是b無法路由到a。


跟tcp沒關係,本質是個路由的問題。簡單來說,外網連內網時,外網沒有內網的路由信息,連接無法建立。內網連外網時,nat轉換了以後,地址發生了轉換,內網地址改為了外網地址,連接可以建立。


推薦閱讀:

QQ 為什麼以 UDP 協議為主,以 TCP 協議為輔?
tcp協議可靠嗎? 怎麼知道自己發出的消息已經被是否被成功接收?
tcp上傳文件時的ack變化?
怎樣生動描述 TCP 的「三次握手」?
tcp協議握手為什要各隨機一個數字並加一?

TAG:計算機網路 | TCP |