我喜欢用很简单的话来概括:
natp是内部机器通过路由器也就是网关向外部发送网络请求时,路由器记住内部机器的ip和端口,同时跟真正发送数据的外网端口绑定,产生一个临时映射表,当收到外网数据以后通过这个映射表将数据转发给内部机器。nat的多种映射类型以后再说。
upnp和nat-pmp差不多,就是在路由器和内部机器提供一个中间服务,内部机器请求upnp将其使用到的端口跟某个外网端口绑定,这样当路由器收到外网请求时先去upnp里查找是否此外网端口已经被upnp映射,如果被映射则将数据转发到内部机器对应的端口。
napt是路由器肯定带的功能,其产生的nat映射表有多种类型,但都有时效,也就是超过一段时间原来的nat映射就无效,然后新建新的nat映射。nat映射必须先由内部机器向外部网络发起请求才会产生。
upnp是把映射关系长期保存下来,外部机器可以主动向内部机器请求网络连接。 所以首先要路由器开启upnp功能(一般由用户去路由器设置里手动开启upnp),然后内部机器的程序要自己实现upnp客户端功能:主动查找upnp服务,主动增加映射、删除映射等。
客户端无法控制natp的映射,可以主动控制upnp映射。
从我目前对go-ethereum源码中p2p的研究来看,以太坊只做了upnpt和nat-pmp的端口映射,而且实现是调用了第三方开源库,但是没有做NATP udp打洞。
比特币源码还没看,不过应该也没有做udp打洞穿越NAT.