V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
zhoudaiyu
V2EX  ›  问与答

NAT 穿透为什么要用 UDP 协议?

  •  
  •   zhoudaiyu · 2021-08-12 11:17:15 +08:00 · 3739 次点击
    这是一个创建于 1200 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有点不太明白做 NAT 穿透很少有用 TCP 协议的? TCP 做穿透有什么不能满足的吗?

    15 条回复    2022-05-29 16:19:55 +08:00
    ipwx
        1
    ipwx  
       2021-08-12 11:18:47 +08:00
    因为 TCP 不可能,UDP 可能。
    trepwq
        2
    trepwq  
       2021-08-12 11:19:38 +08:00 via iPhone
    tcp 有连接状态
    AoEiuV020
        3
    AoEiuV020  
       2021-08-12 11:27:43 +08:00
    握手什么的该背的都没背吗?
    tcp 四元组,建立好的连接双方的 ip 和端口都是确定了的,换个发送方就没法复用这个连接了,udp 可以记住 ip 端口双方交换后直接给对方的 ip 端口发消息就会自动经过 net 转换穿透到内网了,
    AoEiuV020
        4
    AoEiuV020  
       2021-08-12 11:29:16 +08:00
    用 tcp 的内网穿透一般直接叫转发,不说穿透,原理压根就是普通的内网发起的 tcp 连接,
    0o0o0o0
        5
    0o0o0o0  
       2021-08-12 12:30:17 +08:00   ❤️ 1
    因为 nat 穿透首先要设备主动发起连接,才能让 nat 制造一个端口映射,也就是打洞。
    而 tcp 打完洞就和连接对象绑定了,其他人没法连接。
    udp 就只是打了一个洞,之后什么东西都可以进去。
    iceheart
        6
    iceheart  
       2021-08-12 12:40:45 +08:00 via Android
    TCP 难做,UDP 容易做,仅此而已
    desdouble
        7
    desdouble  
       2021-08-12 13:27:27 +08:00
    两个 NAT 后的设备要通信,需要知道对方的地址和端口,他们需要借助于公网上一台可以共同访问的服务器作中转,来确定对方的地址和端口,这个过程叫打洞( punching )。打洞是一种特殊的通信,目的是在双方的 nat 设备上建立起一个临时的 nat 表。由于打洞完成后还要进行其他通信(真正的通信),所以,要求打洞协议是无状态的。就只能使用 udp 。
    desdouble
        8
    desdouble  
       2021-08-12 13:37:22 +08:00
    当然,说“tcp 一定不行”在技术上,逻辑上不严谨。我们的决明子组网产品主要使用了 udp 打洞的技术,在做这个功能的时候,我们查阅了很多论文和资料,有提到 tcp punching 的,但在实践中我们没有成功的尝试过。也没有发现使用 tcp punching 的成熟产品。

    但其实这个问题也算比较模糊啦,要主动跟 nat 后的设备通信,不只打洞一种方式,还可以使用公网服务器中转。花生壳,frp,ngrok,以及我们哲西云的续断内网穿透就是这类产品。
    v2tudnew
        9
    v2tudnew  
       2021-08-12 13:54:01 +08:00
    与其搞 TCP 穿透不如加个可选择开关的 UPNP 功能和自定义端口设置。
    chotow
        10
    chotow  
       2021-08-12 14:06:56 +08:00
    借楼提问,ZeroTier 和 WireGuard 打洞后都是 UDP 协议,遂想用 udp2raw 来包装一下防止 QoS,但是目前搜不到多少资料,比较迷茫。
    对于两个设备,如果一端有公网 IP,那很方便;可是如果两端都是 NAT,ZeroTier 借助 Moon 节点打洞成功了,怎么用 udp2raw 包装呢?
    lysS
        11
    lysS  
       2021-08-12 16:18:29 +08:00
    @chotow 伪装真的有效吗?我看 kcp 的置顶 issue 上说 ISP 是不会针对协议的
    desdouble
        12
    desdouble  
       2021-08-12 17:35:40 +08:00
    运营商是上帝视角,加密伪装这些操作对运营商来说绝大多数都是小儿科的把戏。退一步讲,无法 QoS 的流量,运营商也不会傻到给很高的优先级。写老老实实的代码,至少有 bug 的时候不用怀疑自己的骚操作。
    ysc3839
        13
    ysc3839  
       2021-08-13 09:18:38 +08:00 via Android
    我觉得是因为大多数操作系统及防火墙允许同一个 UDP 的 IP+端口与不同的目标通信。
    虽说理论上 TCP 也可以这么做,但我印象中没哪个操作系统或防火墙允许,要连接不同目标,就必须使用不同的 IP+端口。
    dahakawang
        14
    dahakawang  
       2022-03-01 20:45:21 +08:00
    openp2p
        15
    openp2p  
       2022-05-29 16:19:55 +08:00   ❤️ 2
    @dahakawang 已根据上面的 paper 实现了,原理和 udp 打洞是一样的,实现起来甚至比 udp 还简单 https://github.com/openp2p-cn/openp2p

    tcp 打洞可以避免 Qos ,UDP 打洞可以利用像 quic 和 kcp 这样的加速,各有优势。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   912 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 22:07 · PVG 06:07 · LAX 14:07 · JFK 17:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.