我用INDY的UPD控件做的测试。
现在的问题是这样的:
我在同一个NAT里开两个客户端,IP分别是c1=192.168.0.2、c2=192.168.0.3。端口都是7000,
然后一起连接一个服务器。服务器的IP是s=201.0.0.1,端口是8000,
在服务器中出现两个客户端的NAT后的IP及PORT,
它们分别是(201.0.0.2:7000,        201.0.0.2:1024),
然后再在别外服务器中开一个客户端,IP及PORT为c3=201.0.0.3:7000。这时候,两个客户端都从服务器中得到彼此的NAT后的IP及PORT。
连接图如下:              s (201.0.0.1:8000)-------c3 (201.0.0.3:7000)
                      |
                      |
              nat (201.0.0.2)
                      |
                      |
            -------------------------
            |                       |
            |                       |
c1 (192.168.0.2:7000)        c2 (192.168.0.3:7000)当我用c1向C3发信息时,可以双向发送。
当我用C2向C3发信息时,只能C2向C3发送信息,C3不能向C2发信息,经过查看,发现C2连接c3时的PORT发生了变化,变成了1077了,与S里记录的1024不一样了。这是为什么呀????如果我在同一个NAT里的C1,C2的本地端口改成不一样的,即c1为7000,而C2为7001,那么就可以成功发送了。                   
            

解决方案 »

  1.   

    http://2ccc.com/article.asp?articleid=1993
      

  2.   

    Cassava(车超) 给的例子的功能早就实现了。
    xixuemao() 偶就是不会C,看了C就头痛呀。
      

  3.   

    想用JABBER做的,但是JABBER的服务端都是封装好的,如果出了什么问题的话,都不知道从哪儿下手去解决。
      

  4.   

    “经过查看,发现C2连接c3时的PORT发生了变化,变成了1077了”
    难道楼主的NAT不是锥形的?
    一般情况下,用win2000server做nat的话是锥形nat。
    关于nat的类型,楼主看看这个
    http://www.zahui.com/html/14/36352.htm
      

  5.   

    NAT开的udp端口是有生命期的,一般是5秒
      

  6.   

    是CONE形的,我做过测试的。我两个不同NAT里多开一个CLIENT的话能够成功的。但是如果其中一个NAT里开两个CLIENT的话,就会出现问题了。
      

  7.   

    ppcn上文章比较多,‘看看,还有例子
      

  8.   

    很简单,同一个nat下面的你再放一个udpserver,专门针对同一nat下进行互联,根据ip就可以治到是否是同一nat了,我就是这样搞得,关键是你要把udp通信的几种网络情况都要考虑周全。
      

  9.   

    还有,那个c++的例子存在bug的,我经过测试才发现的~
      

  10.   

    哈哈,是啊,n年没有up了,平时太忙了,所以5角永远都是五角阿,好没面子
      

  11.   

    如果是clone nat,则不会存在两个Client开同样的本地端口时,映射端口会变动的情况不过,映射端口的保持时间是有限制的,具体多少时间我不太清楚,所以,如果你想保持这个端口的话,你需要每隔一段时间向服务器发送一个包(心跳包),用来保持端口
      

  12.   

    还有,bluz() ( ) 的答案前面对,后面肯定错了
      

  13.   

    我这种情况跟iptables很相似!
      

  14.   

    我的类似bt的dll已经封装好了的,问题不会理解错误的,你提交给服务器的端口,和你最终客户端通讯的端口是不同的,客户端通讯端口同羊都是nat随机分配的,写代码的时候多注意一下indy返回的peerport,从同一个用户那里过来的数据也许每次端口都不一样都有可能的
      

  15.   

    TO:农民兄弟
    可是我在NAT里的第一台机器去是用提交给服务器的端口去接收最终客户通讯的呀。而且这个最终客户不止一台,几乎是所有的客户呀。
    而在NAT里的第二台机器去开始变端口的呀。
    我看那个iptables的资料,跟里面的情况有点相似呀。
      

  16.   

    遇到动态的NAT就打洞不成功啦,去年我也花了很多时间在这nat打洞问题上,但始终有一部分NAT穿不过,最终放弃了
      

  17.   

    那我NAT里的第一台客户端怎么可以通呀。
      

  18.   

    呵呵,大部分都是可以打通的。所以最好测试之前先测一个NAT类型,然后再测,可以少走很多弯路。
      

  19.   

    你的结构图画的有些问题,应该是:              s (201.0.0.1:8000)-----nat2 (201.0.0.3)----c3 (XXX.XXX.XXX.XXX:7000)
                          |
                          |
                  nat1 (201.0.0.2)
                          |
                          |
                -------------------------
                |                       |
                |                       |
    c1 (192.168.0.2:7000)        c2 (192.168.0.3:7000)要想C1和C3,或者C2和C3能够正常通讯,需要nat1和nat2相互信任,使它们相互信任的方法就是各自在自己的nat上“打个洞”。大致过程如下:
    1. C1:7000向s:8000发送一个UDP包。这会使nat1创建一个session,端口号假设为A。
    2. C3:7000向s:8000发送一个UDP包。这会使nat2创建一个session,端口号假设为B。
    3. s向nat1:A发送UDP包,这个包会被传送给C1:7000,包内容为nat2的地址和端口号B。
    4. s向nat2:B发送UDP包,这个包会被传送给C3:7000,包内容为nat1的地址和端口号A。
    5. C1:7000向nat2:8000发送一个UDP包,这个包会被nat2丢弃,但是却会使nat1信任由nat2发送来的UDP包了。此后,C3:7000向nat1:A发送的数据就会被传送给C1:7000。
    6. C3:7000向nat1:8000发送一个UDP包,这个包会被nat1丢弃,但是却会使nat2信任由nat1发送来的UDP包了。此后,C1:7000向nat2:B发送的数据就会被传送给C3:7000。说到这里,如果此时C2:7000向nat2:B发送一个UDP包,则这个数据包会被传送给C3:7000,但是C3:7000发送给nat1:A的UDP包只会被nat1转发给C1:7000。因此,如果C2也想和C3双向通讯,C3需要用另外一个端口(比如7001)重复以上建立信任的过程。否则,就会出现楼主所遇到的情况了。
      

  20.   

    补充:
    只有Cone NAT才会使得以上步骤中的5和6及以后的通讯正常进行,如果是Symmetric NAT,则在第5步中,nat1会另外创建一个session(端口号假设为C)用来与nat2建立通讯,结果,后面的通讯就全对不上号了。
      

  21.   

    to:jadeluo(秀峰)
    我的图画的是对,是你理解错了。
    我现在也找到解决方法了。
      

  22.   

    难道你们没有看过IPTABLES的资料吗。
    我的就根IPTABLES差不多的。而且,如果是你CISCO一类的路由器共享上网的话,好象都符合IPTABLES类型的。
      

  23.   

    其实也没什么方法,就是你在局域网中的本地端口不可以重复,也就是说,在同一NAT中,如果已经有一个7001的PORT在运行了,那么你的第二个程序的本地PORT就要改成7002。不过用INDY的UDP控件,要动态来改变PORT好象很困难呀。