UDP穿透NAT打洞问题
打洞理论是这么说的:如果client A 想要向client B发送一个消息,那么不能直接发送,否则会被NAT拦截。必须通知服务器给client B 发送一个通知,通知client B 向client A的方向打洞,那么以后client A就可以直接跟client B联系了。
网上找到的一个解释:
1. Client A向Server发一个UDP包,Server收到后,将发送方的IP地址和UDP端口(NAT A向
Server发送UDP包的端口,而不是Client A的4000端口)通知Client B。之后Client B就需要开始
向这个IP地址和UDP端口发送UDP包了。当然,在下面第2步还未完成之前,Client B向这个IP地址和
UDP端口发送的所有UDP包都会被NAT A丢弃。
2. Client A向NAT B的地址和任意端口发一个包, 发送这个包没有其他目的,只是为了让NAT
A认为从NAT B发送来的UDP包是安全的而已。
我有一个疑问:就是为什么client A直接向client B发送消息会被NAT拦截,但是clinet B向cilent A发送的打洞消息就不会被client A 的NAT拦截呢???
下面是我的想法:
难道是这个client B 给client A 的打洞消息也会被client A 的NAT拦截,但是它的目的已经达到了,就是即使被拦截了,也已经打出了一个洞,从此以后,client A 给client B的消息可以直接发送了。
但是我自己仔细想想不太可能,因为client B给client A 发送的打洞消息被拦截,那么就没有到达client A的这台内网主机,也就不可能在client A的NAT中有这个端口映射,没有端口映射,通过NAT后的clinet A直接发送给clinet B的消息就会加上一个client B 所不知道的外网IP+端口号,对于这个client B的NAT 肯定会拦截。
难道NAT只认IP,不认端口;如果clinet B给client A 的外网IP发过打洞消息(即使这个消息被拦截),那么以后通过这个client A的外网发给 client A的消息都不会被拦截;
但是,我在一个帖子上面看到,NAT是认IP+端口的,那个人换了一个socket ,因为不同socket绑定的不同的服务器端口,所以他用 socket A接收 client 的请求,用socket B去回复client 的时候,client 不能收到消息,也就是说socket B发出的消息不能达到位于NAT后面的client。而如果他用socket A 接收,用socket A回复的话,可以穿过NAT到达client 主机。
这个说明,NAT是认IP,又认端口的。
另外,我自己按照1,2所说的写了自己的代码,但是我是server.client A ,client B,三者同时运行在自己的一台机器上面,我的机器是个内网主机,按照上面的说明,我的client A与clinetB 没法通讯。。。。。
知道内网主机不能做server,因为client不能连接到server,但是我的是可以连接上的(貌似是通过模拟的吧,我的server IP地址就是用的内网IP 192.168.0.X),还有就是知道 有些NAT不支持 “内网环回”(貌似这个说法),就是2个clinet A与clinet B不能位于同一个NAT下面,我不知道我的client A 与client B不能通讯的原因是什么:
1.是由于我的打洞做法错误
2.由于不支持 “内网环回”
如果是原因2,那么说明我的打洞做法是正确的,但是为什么这么打洞是正确 的,我已经说了我的理解是这样打洞是行不通的,那么请告诉我为什么这样打洞是正确的。。。。。。
自己想了很久,还是不知道怎么回事,请有经验的高手跟前辈们指教。本人一向很大方分数。散发100,如果答案满意,可以再加。