P2P技術詳解 : P2P中的NAT穿越(打洞)方案详解 - killelder/cryptocurrency GitHub Wiki

P2P(Peer to Peer)內容概述

P2P即點對點通信, 與傳統的Server Client模式有著明顯的區別
NAT阻礙了主機進行P2P通信 所以要在NAT網路環境中進行P2P通信, P2P必須加入一些穿越NAT的功能

反向鏈結技術 : 一種特殊的P2P(通信雙方只有一方位於NAT設備之後)

這種情況是所有P2P中最簡單的
Client A在NAT之後, 通過TCP端口1234連接到Server的TCP端口1235上
NAT設備為這個連接重新分配了TCP端口62000
Client B通過TCP端口1234連接到服務器端口1235上
因為Client B自己有外網IP地址, 所以Client A可以發起與Client B的通信, 然而Client B如果通過TCP連接到Client A進行P2P通信, 則會失敗

A -> B ok
B -> A XX

所以B如果要跟A通信, 必須要請求Server, 請Server給A一個連接請求, 反過來請A連接到B

B -> Server -> A -> B

基於UDP協議的P2P打洞技術詳解

UDP打動技術士通過中間Server的協助, 各自在各自的NAT網關上建立相關的表項
使P2P連接的雙方發送的Message能夠直接穿透對方的NAT網關
兩台位於NAT設備後面的P2P Client希望在自己的NAT網關上打個洞, 那麼它們需要一個集中Server, 還需要一種用於打洞的Session建立機制

P2P的Session建立原理

  1. A向集中Server發送消息, 請求集中Server幫助建立與B的UDP連接
  2. 集中Server將含有B的內外網地址發給A, 同時集中Server也把A的內外網地址發給B
  3. A開始向B發送UDP數據包, 並且A會自動鎖定第一個給出響應的B的地址二元組, 同理B也會向A發送UDP數據包,
    A與B互相向對方發送UDP數據包是異步的

下面有三種打洞情景

兩客戶端位於同一個NAT設備後面

A會與B嘗試內外網的通信, 然而A與B內網的數據包是一定可以到達的, A與B採用內網的地址信息進行常規的P2P通信

兩客戶端位於不同的NAT設備後面

A往B發送消息, 如果B向A發送消息包之前, B的NAT會認為A發過來的消息是未經授權的外往消息, 會馬上被丟棄
必須等到B也向A的NAT設備發送以後, 才能打開A與B之間的洞

兩客戶位於多層NAT設備之後(不同內網)

後續請看P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解