如题,理论上来说在建立 TCP 连接之后,如果客户端收到东西应该有 ACK 回文,这样客户端就可以安全地释放资源,不用担心重发问题。
今天考虑到一种情况是,假设建立 TCP 连接后,客户端发出消息,但是始终等不到 ACK,这种时候客户端的行为是什么,如果超时重传的话,我看网上资料说超时时间通常在几百毫秒,是否意味着客户端可以在丢包的几百毫秒内确认连接已经中断?但是这里有一个疑惑,毕竟网络环境很复杂,以前经常有单程需要几千毫秒的通信,这种情况下客户端和服务器又是怎么知道对方的情况的呢。
应用层上的需求是,我想知道在建立三次连接后,如果应用层的客户端和服务端想要进行一次可靠的交换数据,是否仍要以三次握手的方式确认,才能保证可靠?而不能做一个比如客户端发出 0.5 秒内无断连则默认发送已经成功这种的逻辑?
====
上述问题在 tls 环境中结论有改变吗?
1
toaruScar 2021-04-06 05:26:48 +08:00 1
TCP 的 retransmission 是基于 RTO ( retransmission timeout )的,RTO 又是由 RTT ( round trip time )计算出来的,所以如果有“单程需要几千毫秒的通信”,那么 RTT 就会很高,导致 RTO 也会很高,使得发送方不会马上 retransmission 。
|
2
LeeReamond OP @toaruScar 感谢回复,另外想到一个问题是,tcp 要四次分手,可靠地注销掉双方机器上开辟出的资源,那如果一方完全没有回复,发出去的包全都石沉大海了,也就没办法四次分手,这种情况下另一方会直接释放资源吗,这是否意味着不可靠
|
3
delpo 2021-04-06 07:41:42 +08:00
@LeeReamond linux 下最后一次分手包发出后会进入 time_wait 状态,就是为了防止数据包丢失,所以要等待一段时间看有没有再收到 retransmission 的包
|
4
delpo 2021-04-06 07:46:35 +08:00 1
@delpo 如果你指的是建立连接后直接就收不到消息了,那发送方会根据二进制指数退避算法一直发送 retransmission 直到超过设置的次数,然后断开连接
|
5
LeeReamond OP @delpo 所以如果我没理解错的话,你的意思是断开连接后系统资源并不立即释放,默认设置要一分钟以后才能释放?另外 timewait 的状态下端口可以绑定新的 socket,这个我觉得也很矛盾
|
6
delpo 2021-04-06 08:53:44 +08:00
|
7
LeeReamond OP @delpo 感谢,默认 socket 都提示不让重复绑定,没写过类似的应用。单进程内 io 复用我觉得挺好理解的,多进程间绑定的话流不就乱了么,不知道数据的哪部分叫谁取走了。
|
8
delpo 2021-04-06 21:10:25 +08:00
@LeeReamond 只要目的地二元组不同就可以分辨数据流传输到哪个 socket
|
9
LeeReamond OP @delpo 确实,很合理,所以意思是面向连接还是独立的,只不过多进程公用一个端口地址
|