P2P就是端到端
我發(fā)一條微信給你,這不是P2P。因為消息并不是直接從我手機發(fā)送到你的手機,而是從我手機先發(fā)送到微信的服務(wù)器,服務(wù)器再轉(zhuǎn)發(fā)到你的手機上(當(dāng)然,轉(zhuǎn)發(fā)給你之前,還會把數(shù)據(jù)存到服務(wù)器),像下邊這樣:

P2P是這樣:

P2P技術(shù)要解決的問題
目前使用的終端設(shè)備(如手機),絕大部分都僅僅擁有特定網(wǎng)絡(luò)下的內(nèi)網(wǎng)IP,而處在不同內(nèi)網(wǎng)環(huán)境中的設(shè)備并不能夠使用內(nèi)網(wǎng)IP直接進行通信。如何通過一定的手段讓這兩個處在不同內(nèi)網(wǎng)環(huán)境的設(shè)備進行直接通信呢?
P2P的知識點
我們的終端設(shè)備(比如手機),一定是存在于某個內(nèi)網(wǎng)環(huán)境下邊的,當(dāng)設(shè)備與內(nèi)網(wǎng)之外的其他設(shè)備進行通信時,需要將內(nèi)網(wǎng)IP轉(zhuǎn)換為一個可以被全球任意設(shè)備訪問到的公網(wǎng)IP,這種技術(shù)叫做NAT,全稱是Network Address Translation,即網(wǎng)絡(luò)地址轉(zhuǎn)換。
根據(jù)轉(zhuǎn)換方式的不同,出現(xiàn)了不同的NAT,理論上有基本NAT,也有一對多NAT,但是現(xiàn)實中基本都是一對多NAT,根據(jù)內(nèi)網(wǎng)設(shè)備與外網(wǎng)進行通信時不同的映射規(guī)則,又分為以下幾種類型:
類型 闡述
錐型NAT(Full-cone NAT)
內(nèi)網(wǎng)ip1:port1會映射到公網(wǎng)ip2:port2,ip1:port1發(fā)往外網(wǎng)的包都將通過ip2:port2發(fā)出;外部任何ip3:port3都可以通過發(fā)送數(shù)據(jù)包給ip2:port2從而與ip1:port1進行通信。
(地址)限制型錐型NAT((Address)-restricted-cone NAT)
內(nèi)網(wǎng)ip1:port1會映射到ip2:port2,ip1:port1發(fā)往外網(wǎng)的包都將通過ip2:port2發(fā)出;外部只有收到過ip2:port2數(shù)據(jù)包的ip3才可以發(fā)送數(shù)據(jù)包給ip2:port2從而與ip1:port1進行通信。
端口限制型錐型NAT(Port-restricted cone NAT)
內(nèi)網(wǎng)ip1:port1會映射到ip2:port2,ip1:port1任何發(fā)往外網(wǎng)的包都將通過ip2:port2發(fā)出;外部只有收到過ip2:port2數(shù)據(jù)包的ip3:port3才可以發(fā)送數(shù)據(jù)包給ip2:port2從而與ip1:port1進行通信。
對稱性NAT(Symmetric NAT)
內(nèi)網(wǎng)ip1:port1任何一個發(fā)往外網(wǎng)ip3:port3的請求,都將使用獨有的公網(wǎng)ip2:port2;外部只有收到過ip1:port1數(shù)據(jù)包的服務(wù)才能返回數(shù)據(jù)。
總的來說,我們程序發(fā)出的包有源地址和源端口,經(jīng)過NAT之后,映射出的公網(wǎng)地址和端口是否會隨著目的地址和目的端口的變化而變化,決定了它是錐型還是對稱型。這句話有點拗口,但我覺得說的很清楚。同時,只有錐型NAT才能進行P2P,原因是由P2P連接的建立過程決定的。
P2P連接建立過程
P2P連接的建立首先需要一個擁有公網(wǎng)IP的中間服務(wù)器S,兩個結(jié)點P1和P2。
1、結(jié)點P1和P2分別發(fā)送數(shù)據(jù)包給S,數(shù)據(jù)包在經(jīng)過NAT時,ip和port進行轉(zhuǎn)換,ip轉(zhuǎn)換為公網(wǎng)ip,port是否轉(zhuǎn)換需要看NAT的具體實現(xiàn)。S拿到轉(zhuǎn)換后的P1和P2的地址。
2、S將P1的地址發(fā)給P2,將P2的地址發(fā)給P1。這里的地址都是NAT地址。
3、P1收到P2地址后,嘗試建立連接,首先發(fā)送消息包給P2(其實是P2的NAT),P2也同樣這樣做,在兩個結(jié)點都收到對方的消息包之后,就可以進行通信了。這個過程也叫做打洞。
之所以需要有打洞這個過程,是因為,NAT會丟棄自己不認(rèn)識的地址包,讓NAT認(rèn)識它的方法,就是發(fā)出一個到這個地址的數(shù)據(jù)包。比如讓A認(rèn)識B,那就讓A發(fā)一個數(shù)據(jù)包給B,不然,B發(fā)給A的數(shù)據(jù)包就會被丟棄。所以打洞的過程不是為了收到對方的數(shù)據(jù)包,而是為了發(fā)送數(shù)據(jù)包給對方,從而認(rèn)識對方。這樣,之后的通信就可以正常進行了。
剛才之所以說只有錐型NAT才可以進行P2P,原因在第三步可以看出來。結(jié)點進行打洞的地址,是通過服務(wù)器拿到的,而這個地址在對稱型NAT的情況下,并不是一定的,可能會隨時發(fā)生變化。也就是說,P1與服務(wù)器通信使用的NAT地址和P2與P1通信使用的NAT地址是不同的(一般情況都是端口不同)。甚至P1與服務(wù)器通信使用的NAT地址都在不斷的發(fā)生變化。這樣讓我們沒辦法拿到隱藏在NAT后邊內(nèi)網(wǎng)設(shè)備的NAT入口,也就沒辦法進行P2P通信了。
對稱性NAT的公網(wǎng)IP地址和端口會在以下情況下發(fā)生變化:
? 與不同的外網(wǎng)地址和端口通信時:當(dāng)內(nèi)網(wǎng)設(shè)備向不同的外網(wǎng)IP地址和端口發(fā)送數(shù)據(jù)時,對稱性NAT會為每個不同的目的地址和端口組合分配一個新的公網(wǎng)IP地址和端口。例如,內(nèi)網(wǎng)設(shè)備先向服務(wù)器A的IP地址和端口1發(fā)送數(shù)據(jù),再向服務(wù)器B的不同IP地址和端口2發(fā)送數(shù)據(jù),那么這兩次通信所使用的公網(wǎng)IP地址和端口很可能是不同的。
? 通信會話重新建立時:如果內(nèi)網(wǎng)設(shè)備與某個外網(wǎng)設(shè)備的通信會話中斷后重新建立,即使目的地址和端口相同,對稱性NAT也可能會分配一個新的公網(wǎng)IP地址和端口。這是因為對稱性NAT會將每個新的通信會話視為獨立的,為其分配不同的公網(wǎng)地址和端口以確保通信的獨立性和安全性。
P2P也用到了一個服務(wù)器,跟微信一樣。但是不同的是,P2P中的服務(wù)器只作為結(jié)點地址的中轉(zhuǎn)站,而微信的服務(wù)器是數(shù)據(jù)的聚寶盆。P2P讓我們的數(shù)據(jù)僅通過P2P連接發(fā)送,而不經(jīng)過任何第三方的服務(wù)器。