终于打洞成功;算是费了九牛二虎之力了,走了不少弯路。不是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/