UDT之P2P打洞大法

本文详细介绍了使用UDT和UDP进行穿透NAT的洞洞打通过程,包括两个主要方案:一是纯用UDT来打洞,二是先用UDP打洞后再绑定UDT。方案涉及Socket创建、连接、穿洞请求和响应等关键步骤,旨在解决跨防火墙通信问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值