现有客户端A和B,A在局域网内,B在外网,有固定IP。
A和B中均设有两个winsock,其中0用于收1用于发,
收的设置一样:
winsock(0).protocal = 1
winsock(0).localPort = 自己公网IP
winsock(0).bind 自己公网IPA的发:
winsock(1).protocal = 1
winsock(1).remoteIp = B的IP
winsock(1).remotePort = B的端口
winsock(1).bind
B的发:
winsock(1).protocal = 1
winsock(1).remoteIp = A的公网IP
winsock(1).remotePort = A的公网端口
winsock(1).bind这样设好后A发往B的消息B能收到,但B发往A的消息A却收不到,
请问是不是设置错误了?
winsock(0)不绑定remoteIp和remotePort是因为winsock(0)还要用来接收其他客户端发的消息。

解决方案 »

  1.   

    原因好像找到了,但却不清楚为什么。
    接上说,
    A连接到服务器后获取到自己的公网端口为:57252,
    然后在A上:
    udpsock(0).bind 57252 '--绑定收消息的端口为自己的公网端口
    udpsock(1).bind 57252 '--绑定发消息的端口为自己的公网端口这时候A发一条消息给B,B能收到。
    B的winsock(0)并没有绑定remotePort,但我用timer显示B上winsock(0)的remotePort竟然为57261,
    而不是A的发消息端口57252。
    有人能帮忙解答吗?
      

  2.   

    除非A也在公網上面。使用 TCP 就可以了,
    A  ->  B  '請求
    A  <-  B  '回復
    ……
      

  3.   

    总算等到有人回答了。。AB都在公网或都在同一NAT下的局域网的多对多连接都已经实现了,而且不需要使用TCP的。从问题上看似乎是B无法穿透A所在的NAT(CONE NAT),但对UDP来说这应该是很简单的事才对的。
    AB在不同NAT下的情形还未做测试,不过从现在的情况看来也有可能是连接不上的了。继续等待高手。
      

  4.   

    现有客户端A和B,A在局域网内,B在外网,有固定IP。 
    这样设好后A发往B的消息B能收到,但B发往A的消息A却收不到。用你的代码,B发往A的消息A肯定是收不到的。
    原因如下:
    A发往B时,因为B在公网上,A可以通过局域网的网关直接访问到B,所以B能接收到消息。并且,A的网关设备会保留此session。
    此时,B只有往A网关的这个session对应的端口发送消息,A网关才会转到A,让A接收到。
    而按照你现在的代码,B发往A的公网IP地址(其他A的网关)的消息,并不是发往 A发消息给B时在A的网关上创建出的session所对应的端口(这个端口号不是固定的)的,这个消息是会被A的网关丢弃的。具体请参见UDP协议打洞的相关文档。
      

  5.   

    楼上的正解!
    我已经找到是这个原因了,所以现在设法在A监听NAT上创建出的session所对应的端口。不过楼上没说到的一点是,如果A往公网上发消息的时候bind了一个固定的本地端口,
    那么A的session所对应的端口就是固定的了。
      

  6.   

    建议楼主再仔细研究一下NAT,那个session对应的端口是由网关创建的,不会是固定的。
      

  7.   

    楼上的,NAT我可能是没研究透,但按我的测试:
    如果winsock.bind,然后发送多条消息,对方看到的winsock.remotePort是变化的,每发一条都不一致,因为本来发送端口在变。
    但如果winsock.bind port,然后发送多条消息,对方看到的remotePort是不变的。
    以上的前提条件是winsock没有被close。
    如果每发一条消息前close然后再bind,则remotePort又是不固定的了。楼上的可以自己写段代码测试一下。
      

  8.   

    以我的理解是,NAT与本地计算机建立了一个端口映射。
    也就是session的端口与bind的端口之间建立了。
    如果winsock不关闭的话这个映射是一直有效的,当然,超过时间被NAT回收的除外。
      

  9.   

    只想说明一点:B看到的A的IP地址和remotePort肯定不是A机器的IP地址和它bind的port。这个remotePort的值取决于网关设备,经楼主测试,A应该winsock.bind port来保证在一定时间内remotePort保持不变,这对于完成A和B的双向UDP通讯是有帮助的。那个session所对应的端口,A没有必要去监听,因为B是知道的,可以由B去告诉A。
      

  10.   

    刚刚测试发现你说的是对的,session端口短期是能保持不变,但一段时间之后却是会变的。
    这个时间还不知道是多长。B看到的A的IP和Port不是A的机器IP和bind的port--这是肯定的,因为B看到的是外网的。A要监听session所对应的端口是因为B发往A的消息都是发往这个端口的,该端口与B获取到A的公网IP对应,
    如果不监听这个端口我还不知道怎么才能收到B发的消息了。
    那个session所对应的端口,A没有必要去监听,因为B是知道的,可以由B去告诉A。
    ---这句我就有点理解不来了,B肯定是知道的,但问题是B应该如何告诉A。
    在A自己知道前A与B的UDP应该是还没有建立的。
    如果B通知Server,Server再告诉A,这是可以,但这样的话又转到A必须监听这个端口才能和B通信了。
    这与上面说的A没有必要监听又相矛盾了。
      

  11.   

    这个问题已经被讨论过很多次了....
    建议你搜索一下以前的帖子
    或者google一下"UPD NAT 穿透"
      

  12.   

    MSDN我搜索过,但没有找到有实质意义的。
    理论谁都能说,但真正实际用起来就会发现光懂理论是不够的。