gpt4 book ai didi

java - Java中准确检测socket发送失败

转载 作者:行者123 更新时间:2023-12-02 00:29:44 27 4
gpt4 key购买 nike

我正在编写一个 Android 应用程序,它初始化 DatagramSocket 以连接到服务器,然后使用无限循环定期(例如每 5 秒)发送数据包。发送代码如下:

DatagramPacket packet = new DatagramPacket(message, message.length);
try {
socket.send(packet);
}
catch (IOException e) {
// Log failure and return
}
// Log success

现在,我可以承受偶尔丢失一个数据包的后果。但我希望能够在连接时检测服务器是否不可用(例如崩溃),在这种情况下,我想保留我发送的消息(在其他时间发送)。最初,我认为每次尝试通过此套接字发送数据包时都会引发异常,因此能够处理将消息存储在我的 catch block 中。事实上它部分有效。我通过关闭服务器来模拟服务器崩溃,当我发送数据包时,我开始收到异常消息 sendto failed: ECONNREFUSED (Connection returned) 。问题是,并不是每次尝试发送都会抛出异常,而是每次尝试都会抛出异常 - 所以我的日志看起来像

Success, Error, Success, Error, ...

据我了解,在服务器不可用后第一次尝试发送数据包时,数据包会被发送,套接字不会等待查看是否有错误消息,并且会记录成功。然后,在下一次尝试时,套接字尝试发送数据包,查看之前的错误消息,并抛出异常而不发送数据包,从而导致记录错误。但是,由于数据包未发送,因此后续尝试发送数据包时将不会再次抛出异常。这是我在看到日志后做出的假设,所以我的推理可能是错误的。

我的问题是,有没有办法确保每次服务器不可用时都会抛出异常?或者有没有其他方法可以检测套接字的另一端已悄然断开连接?我尝试在循环内检查 socket.isConnected(),但它总是返回 true

最佳答案

DatagramSocket 根据定义是无连接的——这是一个关于 differences between UDP and TCP 的好页面。为了后代。如果您收到任何错误,则表明您正在向本地网络上的服务器发送数据,而该服务器没有响应 arp - 或者是我们的默认网关正在消失,而这种可能性较小。您的任何 send 消息返回错误非常取决于操作系统和网络,不应依赖 IMO。这也意味着,如果您在您和服务器之间放置一个路由器,那么我相信 没有 send 方法会返回错误。

如果您需要查看服务器是否已启动并已收到您的消息,那么我建议您向服务器添加代码以将确认发送回客户端。您不希望客户端发送并等待每个数据包的确认,但可能发送 X 个数据包,然后等待所有 X 的确认,或者有一个带有重传线程或其他东西的等待表。

当然,一旦您开始走这条路,您可能需要考虑使用 Jgroups或切换到 TCP/IP。 :-)

关于java - Java中准确检测socket发送失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9309789/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com