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

UDP over TCP 如何控制丢包?

  •  
  •   body007 · 282 天前 · 1976 次点击
    这是一个创建于 282 天前的主题,其中的信息可能已经有所发展或是发生改变。

    众所周知 TCP 可靠但不如 UDP 快,但 UDP 会丢包。很多语音视频都是 UDP ,因为丢包只会影响视频质量,但可以接受。

    最近搞了个 UDP over TCP ,解决运营商恶意 UDP 丢包,以及墙的监控等等。

    结果功能是可以了,但是用 WhatsApp 测试视频时傻眼了,视频会卡卡的,并且播放好几秒之前的图像,时间越久播放的图像越旧。用纯 UDP 转发就不会这样,只是视频图像偶尔会瞬间从一个画面卡到最新画面。

    我想我是不是可以人为的在客户端丢弃一些数据包,但是这个丢包策略要如何控制?希望有大神解惑。

    如果 UDP over TCP 效果这么差,为啥 GitHub 上还有很多相关项目?难道是他们的 UDP 场景不怕上面那种问题吗?

    大佬有没有相关思路啊。

    19 条回复    2024-04-08 23:59:17 +08:00
    bobryjosin
        1
    bobryjosin  
       282 天前 via Android
    udp over tcp 只是解决了被运营商恶意丢包,tcp 长连接跨境是会被 gfw 恶意随机阻断重置所以断断续续,解决办法:购买高优先级的线路,例如 iplc 专线,cn2 这些。
    xenme
        2
    xenme  
       282 天前 via iPhone
    udp over tcp ,都走了 tcp 怎么会丢包?
    我理解可能重传导致你 udp 包乱序而已,包肯定不会丢,这是 tcp 保证的。
    ryd994
        3
    ryd994  
       282 天前 via Android
    TCP 本来就有实时性不强的问题
    其实你没必要走正常的 TCP socket
    在 UDP 包外面套一层 TCP 头就完事了
    除了三次握手,我不信墙还真的会记你的 sequence number
    Jirajine
        4
    Jirajine  
       282 天前
    udp over tcp 这个问题无解,tcp 就没法控制丢了的包不重传,上层应用根本都没法知道有包丢掉了。
    为了解决 qos ,一般都是伪造成 tcp/icmp ,但这样也就没法通过 tcp tunnel 。
    quic 彻底普及取代 tcp 后就没有这些问题了,不但解决 udp 地位低下的问题,且 quic 不像 tcp ,它是可以构建不可靠信道的。
    hronro
        5
    hronro  
       282 天前
    UDP over TCP 只有在整个 UDP 都被封了的情况下才有意义, 不然就是纯纯的智商税.

    像你说的那种问题, 在 UDP over TCP 就是无解的.
    datocp
        6
    datocp  
       282 天前
    多年前电信网络才会遇到,刚开始可以 socks5 测试 4K 视频,然后基本 30 分钟以后就掉到 320p 。
    以观察的经验来看猜测是类似累积流量。

    目前家里用的正统的 https 的 VPN 软件 softether ,然后 cron 定时更换连接端口就这么简单。自从去年 10 月份开始连接同一端口出问题,又正常到至今。。。而且 softher 它可以多线路借道,官方甚至有个 mesh 的实现。目前家里直接用 N1 电信看 youtube 没问题。
    body007
        7
    body007  
    OP
       282 天前
    @bobryjosin @xenme @ryd994 @Jirajine @hronro @datocp 感谢各位大佬的解惑,看来这问题是无解了,那我还是用自己写的插件,用 UDP 转发 UDP 吧,反正平时用 UDP 也只是 WhatsApp 打视频和语音,用得少。我自己写的插件已经在搬瓦工稳定运行超 2 年了。之前在 GitHub 看到很多人想要 UDP over TCP 功能,自己实现了才发现意义不大,有点小失望。


    这是我开源的插件,已经支持同时转发 TCP 和 UDP ,并且也加了 UDP over TCP 逻辑。挂到 GitHub 上 解决 SIP003 插件不支持 UDP 的情况吧。
    https://github.com/shadowsocks/shadowsocks-org/issues/180#issuecomment-1626915370
    Jirajine
        8
    Jirajine  
       282 天前
    @body007 看了那个帖子,有人发通过 udp 转发使用 HTTP3 效果不如 UDP over TCP ,可能是 mtu 不对,TCP 会自动协商 mtu 所以错了也没什么影响,但 udp 就依赖上层协议了。
    之前买了个 ss 协议支持真 udp 转发的机场,用来转发自己的 wireguard 隧道,发现性能很差,居然比 UDP over TCP 慢很多。一开始以为是 qos ,但后来抓包发现有很多 ip fragmentation ,调整 mtu 后瞬间就好了,配合 quic 0-rtt 打开网站响应极致丝滑。
    至于 UDP over TCP 的意义,其实就两点,一是连通性,部分公共网络会阻断所有 UDP 流量,也有不少只支持 TCP 的代理提供商,尤其是被攻击的时候关掉 UDP 。第二点就是在无法使用 fake tcp 等需要完整 3 层的情况下缓解运营商 qos ,但 tcp 究竟比 udp 优先级高多少也不好说,较差的网络环境下可能通过前向纠错的隧道表现会更好。
    wdf1286
        9
    wdf1286  
       282 天前 via Android
    你对 udp over tcp 的理解不对,正确的做法是给 udp 包装一层 tcp 头,然后通过 rawsocket 或者 tuntap 的方式发送与接收,而不是直接把 udp 包通过 tcp 连接去发送和接收
    body007
        10
    body007  
    OP
       282 天前
    @Jirajine 这个就不清楚了,每台深入了解。我搜索的 udp over tcp 给我的感觉就是用 tcp 转发 udp 。只是不知道最终效果并不好而已。我自己弄的 UDP 转发 UDP 没啥问题,那我还是老老实实用 UDP 转发 UDP 吧。
    body007
        11
    body007  
    OP
       282 天前
    @wdf1286 嗯嗯,可以用现成的 https://github.com/wangyu-/udp2raw ,我以为是用 TCP 转发 UDP ,只是效果不好。我个人还是老老实实用 UDP 转发 UDP 吧。
    DefoliationM
        12
    DefoliationM  
       281 天前 via Android
    我也是 UDP over TCP ,用来玩 switch 联机游戏都不卡,可能是代码实现有问题或者服务器连接效果不好。
    body007
        13
    body007  
    OP
       281 天前
    @DefoliationM 我也搜了一些资料,说是网络好的时候没问题,网络差的时候由于 TCP 重传就会导致我遇到的问题。我还是用 UDP 转发 UDP 吧,主要是为了我自己写代码加密 UDP 数据,不然直接用 ss 就行额。
    julyclyde
        14
    julyclyde  
       279 天前
    @wdf1286 加这样的 header ,不会被对方内核认为是错误包然后 RST 回来吗?
    wdf1286
        15
    wdf1286  
       278 天前
    @julyclyde 可以用 sysctl 设置不返回 rst
    heiher
        16
    heiher  
       232 天前 via Android
    支持 UDP over TCP 的 Socks5 ,通过 QUIC 看视频体验上与 TCP 没有明显的差别。

    https://github.com/heiher/hev-socks5-server
    body007
        17
    body007  
    OP
       231 天前
    @heiher QUIC 底层还是 UDP 额,我看 github 上其他人要解决的问题是 UDP 被封,只能用 TCP 的情况,希望通过 TCP 传输 UDP 数据额。
    heiher
        18
    heiher  
       231 天前 via Android
    @body007 对的,QUIC(UDP) over TCP 。
    thom
        19
    thom  
       20 天前
    @body007 好像你把 github 里的内容删除了~使用微信视频通话测试,并没有发现明显延迟。

    1. 日志里确认走的是 udp
    2. udp over tcp / wss 和 udp over udp 没有明显差异。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5429 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 09:12 · PVG 17:12 · LAX 02:12 · JFK 05:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.