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

2021-04-06 04:42:52 +08:00
 LeeReamond

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

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

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

====

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

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

事实上不论什么状态都可以绑定新 socket,端口复用的应用是很常见的
LeeReamond
2021-04-06 21:01:12 +08:00
@delpo 感谢,默认 socket 都提示不让重复绑定,没写过类似的应用。单进程内 io 复用我觉得挺好理解的,多进程间绑定的话流不就乱了么,不知道数据的哪部分叫谁取走了。
delpo
2021-04-06 21:10:25 +08:00
@LeeReamond 只要目的地二元组不同就可以分辨数据流传输到哪个 socket
LeeReamond
2021-04-06 21:52:56 +08:00
@delpo 确实,很合理,所以意思是面向连接还是独立的,只不过多进程公用一个端口地址

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/768219

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX