我所说的保证是指 TCP 的普遍理解特性,即如果数据包损坏或丢失,则它将不被确认并被重新发送。
考虑发送方发送一些数据并立即关闭套接字的情况(在 java 中)。如果该数据在途中丢失或损坏自身,接收者将永远无法获得它吗?或者发送者套接字是否等待并且直到所有适当的ACK都被读回才真正关闭?
我自己尝试过追溯 socket.close() 方法,但这很困难,因为不仅有许多内部套接字实现,而且功能拆分成几个方法名称不明确的路径。
我所说的保证是指 TCP 的普遍理解特性,即如果数据包损坏或丢失,则它将不被确认并被重新发送。
考虑发送方发送一些数据并立即关闭套接字的情况(在 java 中)。如果该数据在途中丢失或损坏自身,接收者将永远无法获得它吗?或者发送者套接字是否等待并且直到所有适当的ACK都被读回才真正关闭?
我自己尝试过追溯 socket.close() 方法,但这很困难,因为不仅有许多内部套接字实现,而且功能拆分成几个方法名称不明确的路径。
考虑发送方发送一些数据并立即关闭套接字的情况(在 java 中)。如果该数据在途中丢失或损坏自身,接收者将永远无法获得它吗?
TCP 将重新传输,至少在其重试计时器或计数器到期之前,它会放弃并停止连接。
或者发送者套接字是否等待并且直到所有适当的ACK都被读回才真正关闭?
是的。这发生在 TCP 中,而不是 Java 中。
大多数资源管理发生在 JVM 之下的操作系统级别。
在 TCP 协议的情况下,它完全由操作系统管理,发生的情况是
Application tells JVM to send data on TCP Stream
JVM access OS functions to perform data send task.
OS manages TCP protocol.
data gets sent over the network.
数据从 JVM 复制到操作系统内存空间,因此即使 JVM 中止 TCP 合同,仍应得到适当处理。
如果 JVM 停止或请求操作系统关闭套接字,它应该保持套接字打开,直到另一个端点确认所有数据已到达或另一个端点关闭。
由于 JVM 仅与操作系统接口,因此您不会在 Java 库中看到此管理代码,它们假定操作系统和 JVM 正确处理了管理。
您应该使用Socket.shutdownOutput()然后等待关闭事件,就好像远程主机关闭了连接一样。此方法是对shutdown() C 套接字函数的包装,它接受一个参数来决定关闭哪个网络流。