zoukankan      html  css  js  c++  java
  • 关于C# UDP 打洞穿越NAT的问题

        本人在最近正在做工作相关的UDP网络通信的开发,想把可在局域网上运行的程序搬到公网上去,但是涉及到一个问题,所有客户端跟服务器通讯没有问题,但是客户端与客户端之间的通讯受到了阻碍。这期间也看了不少先辈们的相关资料,到处都是打洞的源代码,但是我始终有点想不通:

        NAT有几种形式,能够实现UDP的打洞的只有NPAT亦即CONE NAT,这种NAT共享一个外部地址,通过建立SESSION,分配不同的端口号来帮助内部的客户机通信。

        由于存在第三方的SERVER,分别位于两个NAT内的客户机CA和CB想要互相通信,需要先向SERVER发出一个P2P打洞请求。

        这里有一点不明白:CA向SERVER注册自己时,其NAT为其打开了一个端口6001,于是,CA与服务器可以互相通信;另个CB向SERVER注册自己时,其NAT为其打开了一个端口8002,CB也可以与SERVER正常通信。当然,这两个操作都是由客户端首先发起的,NAT允许内部与外部主动通信,并且经由原地址(也就是服务器地址)返回的消息,可以正常接收。但是对于CA打开的6001端口和CB打开的8002端口,任何非来自于SERVER的UDP包将被各自的NAT所抛弃。

        现在问题出来了:我看到很资料上说,CA如果想与CB直接通信,需要先向SERVER发出一个请求,让服务器发给CB一个命令,命令CB向CA发起一个打洞的数据包,CA做出回应,各自建立数据通道,也就是各自的NAT上的SESSION。但是!服务器可以发给CB一个命令,因为是CB注册服务器时主动联接的服务器,CB也可以遵从命令向CA发出一个打洞请求。这里的打洞请求的地址应该是多少呢?也许有人说,CA不是向服务器注册地址了吗?服务器肯定记录了CA的6001端口。不错,我们可以向6001发出数据包。由于这个数据包不是SERVER发起的,而6001是为了与SERVER通信才建立的,那么,CA的NAT肯定会抛弃这个不请自来的数据包。但是,也有人提到,此时即使CB向CA的请求被拒绝,但是此时也在CB的NAT上建立了一个SESSION,打开了一个指向CA的端口(这是我猜的,比如是8003)。但是CA还不知道,服务器怎么知道?服务器不知道的话,怎么把这个消息告诉给CA?CA的回复打洞请求的数据包发向哪个地址?以后与CB的通信,岂非需要单独保留一个地址?

        诚邀各位高手不吝赐教!

  • 相关阅读:
    MSSQL如何将查询结果拼接成字符串
    SQL删除指定条件的重复数据,只保留一条
    清除日志
    jsp使用
    Eclipse使用
    SSM框架开发遇到的问题
    SpringMvc学习
    大中华~~汉字
    Word技巧设置
    AWS-资源访问慢分析
  • 原文地址:https://www.cnblogs.com/saptechnique/p/1873222.html
Copyright © 2011-2022 走看看