UDT之P2P打洞大法
发布日期:2021-05-24 23:11:15 浏览次数:23 分类:精选文章

本文共 1832 字,大约阅读时间需要 6 分钟。

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

上一篇:p2p打洞技术文章
下一篇:SQLSERVER DBCC命令大全

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年05月01日 07时52分34秒