现有客户端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)还要用来接收其他客户端发的消息。
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)还要用来接收其他客户端发的消息。
接上说,
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。
有人能帮忙解答吗?
A -> B '請求
A <- B '回復
……
AB在不同NAT下的情形还未做测试,不过从现在的情况看来也有可能是连接不上的了。继续等待高手。
这样设好后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协议打洞的相关文档。
我已经找到是这个原因了,所以现在设法在A监听NAT上创建出的session所对应的端口。不过楼上没说到的一点是,如果A往公网上发消息的时候bind了一个固定的本地端口,
那么A的session所对应的端口就是固定的了。
如果winsock.bind,然后发送多条消息,对方看到的winsock.remotePort是变化的,每发一条都不一致,因为本来发送端口在变。
但如果winsock.bind port,然后发送多条消息,对方看到的remotePort是不变的。
以上的前提条件是winsock没有被close。
如果每发一条消息前close然后再bind,则remotePort又是不固定的了。楼上的可以自己写段代码测试一下。
也就是session的端口与bind的端口之间建立了。
如果winsock不关闭的话这个映射是一直有效的,当然,超过时间被NAT回收的除外。
这个时间还不知道是多长。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没有必要监听又相矛盾了。
建议你搜索一下以前的帖子
或者google一下"UPD NAT 穿透"
理论谁都能说,但真正实际用起来就会发现光懂理论是不够的。