UDT之P2P打洞大法
終於打洞成功;算是費了九牛二虎之力了,走了不少彎路。不是UDT不好用,而是我思維混亂了。
總結一下吧,順便也方便一下還沒有打洞成功的同行。
第一個方案:
純用UDT來打洞,意思是不用UDP來先打洞,然後繫結UDT的方式。
Server C
Client A Client B
1. A和B先建立一個UDT的Socket來連線伺服器,負責和Server C通訊。
簡稱 AA ,BB Socket。
----------------------------------------
引數設定:AA 或者 BB = UDT.socket(AF_INET,SOCK_DGRAM,0)
setsockopt UDT_REUSEADDR 為 True
bind(AA 或者 BB,local)
----------------------------------------
2.連線 ServerC
AA,BB:
UDT.connect(AA或者BB ServerC)
3.B發起穿洞請求給Server C,ServerC獲取 B 的NAT IP和Port後發給 A:
Server C
/ ^\
/ \
/ \
v/ \ Client A Client B
4. Client A收到訊息後,再返回給 Server C,讓C中轉給B自己的NAT IP和Port
AA Send
Client A 開始建立2個Socket Sa 和 Sa' :
-----------------------------------
Sa Port = AA.Port
socket(Sa..)
setsockopt(Sa, 0, UDT_MSS, new int(1052), sizeof(int));
bind(Sa..)
listen(Sa,..)
-----------------------------------
Sa' Port = AA.Port
socket(Sa'..)
setsockopt(Sa', 0, UDT_MSS, new int(1052), sizeof(int));
bind(Sa'..)
connect(Sa',B)
用Sa來listen,用Sa'來連線B,當然這裡的連線是讓路由器建立個Session。
Server C
/^ / ^\
/ / \
/ / \
/ / \
/ / \
/ v/ \ Client A \ Sa(listen) \ Sa'------> Client B
5. Clinet BB 收到 來自 來自CLient AA的經伺服器轉發的資訊後,建立一個
新的Socket ,稱為 Sb
----------------------------------------
Sb.Port = BB.Port
socket(Sb..)
setsockopt Sb UDT_REUSEADDR 為 True
setsockopt(Sb, 0, UDT_MSS, new int(1052), sizeof(int));
bind(Sb..)
connect(Sb,AA)
Server C
/^ / ^\
/ / \
/ / \
/ / \
/ / \
/ v/ \ Client A \ Sa(listen) Client B
Sa'------->
<---------------Sb
---------------->
6.打洞成功 Sa' 和 Sb P2P通訊。
可能還有細節上的錯誤,沒有來的及多測試。
------------------------------
第2個方案:用UDP來打洞,然後UDT設定 UDT_RENDEZVOUS來繫結打洞後的埠。
這個UDP打洞非常順利。但是由於bind(UDT,UDP)的時候出錯,程式報異常。測試終止。
有時間再好好看看是哪裡的原因吧。說明一下,我用的是Delphi寫的程式,udt.dll是自己
用C++Builder製作出來的。CVS上的原始碼我修改的地方也不多。也不是關鍵的程式碼。
想不出來是哪出的錯,所以,目前就放棄了。
原址:https://sourceforge.net/p/udt/discussion/852996/thread/38a28eaf/