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

TCP 协议中的 ACK 应该怎么理解,数据包如果在传输过程中丢失,双方都会得到响应吗?

  •  
  •   LeeReamond · 2021-04-06 04:42:52 +08:00 · 1577 次点击
    这是一个创建于 1336 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,理论上来说在建立 TCP 连接之后,如果客户端收到东西应该有 ACK 回文,这样客户端就可以安全地释放资源,不用担心重发问题。

    今天考虑到一种情况是,假设建立 TCP 连接后,客户端发出消息,但是始终等不到 ACK,这种时候客户端的行为是什么,如果超时重传的话,我看网上资料说超时时间通常在几百毫秒,是否意味着客户端可以在丢包的几百毫秒内确认连接已经中断?但是这里有一个疑惑,毕竟网络环境很复杂,以前经常有单程需要几千毫秒的通信,这种情况下客户端和服务器又是怎么知道对方的情况的呢。

    应用层上的需求是,我想知道在建立三次连接后,如果应用层的客户端和服务端想要进行一次可靠的交换数据,是否仍要以三次握手的方式确认,才能保证可靠?而不能做一个比如客户端发出 0.5 秒内无断连则默认发送已经成功这种的逻辑?

    ====

    上述问题在 tls 环境中结论有改变吗?

    9 条回复    2021-04-06 21:52:56 +08:00
    toaruScar
        1
    toaruScar  
       2021-04-06 05:26:48 +08:00   ❤️ 1
    TCP 的 retransmission 是基于 RTO ( retransmission timeout )的,RTO 又是由 RTT ( round trip time )计算出来的,所以如果有“单程需要几千毫秒的通信”,那么 RTT 就会很高,导致 RTO 也会很高,使得发送方不会马上 retransmission 。
    LeeReamond
        2
    LeeReamond  
    OP
       2021-04-06 06:10:48 +08:00 via Android
    @toaruScar 感谢回复,另外想到一个问题是,tcp 要四次分手,可靠地注销掉双方机器上开辟出的资源,那如果一方完全没有回复,发出去的包全都石沉大海了,也就没办法四次分手,这种情况下另一方会直接释放资源吗,这是否意味着不可靠
    delpo
        3
    delpo  
       2021-04-06 07:41:42 +08:00
    @LeeReamond linux 下最后一次分手包发出后会进入 time_wait 状态,就是为了防止数据包丢失,所以要等待一段时间看有没有再收到 retransmission 的包
    delpo
        4
    delpo  
       2021-04-06 07:46:35 +08:00   ❤️ 1
    @delpo 如果你指的是建立连接后直接就收不到消息了,那发送方会根据二进制指数退避算法一直发送 retransmission 直到超过设置的次数,然后断开连接
    LeeReamond
        5
    LeeReamond  
    OP
       2021-04-06 08:25:10 +08:00
    @delpo 所以如果我没理解错的话,你的意思是断开连接后系统资源并不立即释放,默认设置要一分钟以后才能释放?另外 timewait 的状态下端口可以绑定新的 socket,这个我觉得也很矛盾
    delpo
        6
    delpo  
       2021-04-06 08:53:44 +08:00
    @LeeReamond 是的,所以这也是高连接数形况下为什么要减少 time_wait 状态的原因,否则系统资源就会被耗尽.

    事实上不论什么状态都可以绑定新 socket,端口复用的应用是很常见的
    LeeReamond
        7
    LeeReamond  
    OP
       2021-04-06 21:01:12 +08:00 via Android
    @delpo 感谢,默认 socket 都提示不让重复绑定,没写过类似的应用。单进程内 io 复用我觉得挺好理解的,多进程间绑定的话流不就乱了么,不知道数据的哪部分叫谁取走了。
    delpo
        8
    delpo  
       2021-04-06 21:10:25 +08:00
    @LeeReamond 只要目的地二元组不同就可以分辨数据流传输到哪个 socket
    LeeReamond
        9
    LeeReamond  
    OP
       2021-04-06 21:52:56 +08:00
    @delpo 确实,很合理,所以意思是面向连接还是独立的,只不过多进程公用一个端口地址
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4219 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 01:03 · PVG 09:03 · LAX 17:03 · JFK 20:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.