2

我正在研究一个 Java 心跳传感器,它只会告诉你对方是否死了。我发现了一些像这样的代码

        isConnected = kkSocket.isConnected() &&
                      !kkSocket.isClosed() &&
                      InetAddress.getByName(serverAddress).isReachable(1000);

这是一个可靠的方法吗?我对这条线感到困惑:

InetAddress.getByName(serverAddress).isReachable(1000);

那是为了什么 - 如果我在“localhost”上进行测试(即不是真正的联网示例,只有一台机器),它会起作用吗?谢谢

4

2 回答 2

2

这些都没有任何用处。该isConnected()方法告诉您是否曾经调用connect()(隐式或显式)或通过accept();接收到套接字。该isClosed()方法告诉您是否曾经调用过close();该isReachable()方法仅告诉您主机是否可访问,并且它会以每次成功调用时额外的 TCP 连接设置和拆除为代价。

它与连接的状态没有任何关系。检测 TCP 连接错误的唯一可靠方法是尝试对其进行写入。

于 2013-03-19T02:07:07.713 回答
2

这取决于您所说的“如果对方死了”是什么意思。

首先,isConnected()打电话是没有用的。这只是询问 Socket 是否在过去的某个时间点连接过。时期。

其次,isClosed()打电话是没有用的。

第三,isReachable()电话用处不大。它确实为您提供了一定程度的保证,即服务的主机在基本网络级别是活动的并且可以访问。(具体来说,它告诉您 ICMP Ping 数据包正在到达主机,并且响应正在返回。)但是,这并不能告诉您与服务的 TCP/IP 连接是否有效,或者服务本身是否有效仍然正常运行。实际上,主机可以响应 Ping 数据包,并拒绝或忽略连接到服务的尝试。

事实上,确保服务真正活跃(在有用的意义上)的唯一方法是尝试使用它。这意味着什么将取决于服务的性质。对于典型的同步服务,您将向套接字输出流写入请求“消息”,然后尝试从输入流中读取回复“消息”。(您应该确保在阅读文章时使用超时...):

  • 如果服务已终止或 TCP/IP 连接已断开,您应该得到一个 SocketException 或类似的。(但请注意,断开的 TCP/IP 连接并不一定意味着服务不存在。您可能只需要再次连接。)
  • 如果服务“卡住”,您可能会在写入或读取时遇到超时。
  • 如果存在网络问题,您可能会遇到超时,或者您可能会遇到某种 SocketException。

如果上述情况均未发生,则表明您的服务是“活动的”,尽管它可能仅对您发送的请求类型是“活动的”。

显然,您还需要检查响应是否符合预期。例如,为每个请求发送 501 或 503 响应的 HTTP 服务在有用的意义上是不活跃的。


那是为了什么 -isReachable如果我在“localhost”上进行测试(即不是一个真正的联网示例,只有一台机器)会起作用吗?

我不认为有一个明确的答案。这取决于操作系统是否支持环回网络地址上的 ICMP 协议。我不希望它起作用,因为 AFAIK 在环回上没有真正的 ICMP 用例。

于 2013-03-19T03:34:39.217 回答