• 这是一个老问题了,今天有人遇到问我,写篇文章简单说明一下不同 NAT 类型的区别以及如何打洞。

    映射方式

    1.Endpoint Independent Mapping ( Full cone )

    不区分终结点的映射,A 使用本地端口 P1 连接一个服务器,外网端口 P2 收到的任何数据包会转发到机器 A 上,跟直连没有什么区别,不需要打洞

    2.Address Dependent Mapping ( Restricted cone )

    基于地址的映射,A 使用本地端口 P1 连接服务器 B,外网端口 P2 收到来自 B 的包转发到机器 A 上

    3.Address and Port Dependent Mapping ( Port-restricted cone )

    基于地址和端口的映射,A 使用本地端口 P1 连接服务器 B,外网端口 P2 收到来自 B 特定端口的包会转发到机器 A 上,实际使用中与 2 没有太大区别

    4.Symmetric NAT

    具有 IP 和 端口的限制,且会为每一个 Session 分配一个新的端口,这个端口号通常是递增的,但是也有随机的,随机的一般无解。

    基本过程

    首先 A 使用内网端口 AP1 向服务器建立连接,服务器记录 A 的公网端口 AP2

    B 使用内网端口 BP1 向服务器建立连接,服务器记录 B 的公网端口 BP2

    用户 A 再次使用内网端口 AP1 向 B 的公网端口 BP2 发送一些信息,这些信息会被 B 的路由丢掉,但是由于 A 向 B 发了信息,B 现在可以向 A 合法发送内容了

    此时的问题在于 A 刚刚使用哪个公网端口向 B 发送了信息

    如果双方都是 NAT 2 或者 3 的话,A 刚刚给 B 发送信息的端口,通常等于 AP2 , B 只需要使用内网端口 BP1 向 AP2 发送数据,就可以 P2P 通讯了。

    如果 A 是 NAT 4 的话,刚刚这个端口不会等于 AP2

    在一部分的路由实现中,这个端口是递增的,所以 B 可以在 AP2 的基础上不断递增进行连接

    如果仍然连接失败,则这个端口可能是随机分配的,这这情况下基本就可以放弃了,如果仍要连接,可以尝试以下步骤(未测试):

    1. A 不停的 与 B 进行连接,NAT 会在路由表上留下很多端口。

    2. B 对 A 进行“扫端口”,直到找到一个连接成功的端口。

    3. 连接成功建立 ,A 停止新建连接,B 也停止扫描端口。

    如果双方都是 NAT 4 的话,不要抱任何希望。

    Talk is cheap , show me the code

    On the way

    过几天我会发布一个完整 P2P 视频直播的例子,服务器和客户端全部开源

    YY 两句

    看看以前的文章,真的想删掉,但是又不舍得删。

    也许有的时候,写博客就是为了打自己的脸。