2 回答
TA贡献1847条经验 获得超7个赞
TCP 是一种基于字节的媒体。它会跟踪您发送的每个字节。在报告之前等待一段时间SocketTimeoutException
。它可以从短暂的网络故障中自动恢复。您可以访问bytesTransferred
异常对象上的字段。这将为您提供保证已到达目的地的字节数。可能还有几个字节到达目的地,但绝对没有办法知道。
为了您的目的,您可以 (1) 跟踪您的消息长度 (2) 实现消息级别ack
。
(1) 跟踪您的消息长度
你byte[] len = DataConverter.toBytes(message.length);
可以有一个ArrayList
的Integers
,并添加len
到列表中。现在,当发生异常时,您可以使用此列表来了解有多少最后一条消息未送达。
(2) 实现消息层 ack
您可以同时使用套接字的InputStream
和OutputSteam
。在接收方,在阅读消息后,您可以向发送方发送回复。在发件人方面,您可以收听InputSteam
,当您收到回复时,您将知道您的消息已成功送达。
老实说,正确地实现这些,尤其是#2,是一个可观的编程挑战。祝你好运!
TA贡献1780条经验 获得超5个赞
您应该定期进行自己的探测,看看它是否还活着。记录所有已发送消息的日志,以便如果套接字确实断开连接,那么您将获得服务器上可能已发送或未发送的列表。当连接重新联机时,您可以比较丢失的内容并发送差异,或者简单地再次发送。
关于你对 keepalive 的评论的注释。javaDoc 指出,(强调我的):
当为 TCP 套接字设置了 keepalive 选项并且2 小时内没有在任一方向上通过套接字交换数据时(注意:实际值取决于实现),TCP 会自动向对等方发送一个 keepalive 探测。
2 小时是等待默认保持活动检查的很长时间,因此您应该自己进行探测以查看它是否还活着。
至于您的问题的答案:除非故障发生在内部,否则您的服务器和客户端无法立即知道您的连接是否已断开。它不知道地球另一端的网络连接是否有问题,或者目标服务器是否只是有一个非常糟糕的 ping(10 秒?),因此,它需要等待响应而不是直接抛出错误离开。
您需要编写考虑这些问题的代码。如上所述,消息日志是一种方法。
添加回答
举报