【问题标题】:Java Networking IssueJava 网络问题
【发布时间】:2011-07-04 20:16:03
【问题描述】:

我们连接了一个路由器和 3 台 PC。

  1. PC1:192.168.1.2(无线)
  2. PC2:192.168.1.3(无线)
  3. PC3: 192.168.1.6

默认网关:192.168.1.1

当 PC3 尝试使用来自 this forum post 的代码查找连接的 PC 时,它只返回默认网关的 IP 地址(该地址是唯一可访问的地址)。

我尝试增加isReachable() 方法的超时时间。但它仍然只返回默认网关地址。

我尝试对单个 IP 地址执行此操作。

try {
            InetAddress temp2 = InetAddress.getByAddress(new byte[]{(byte) 192, (byte) 168, (byte) 1, (byte) 2});
            if (temp2.isReachable(1100)) {
                java.lang.System.out.println("IP Address: " + temp2.getHostAddress() + " has connection.");
            }else{
                java.lang.System.out.println("IP Address: " + temp2.getHostAddress() + " has no connection.");
            }
        } catch (Exception ex) {
            java.lang.System.out.println("Error: " + ex.getMessage());
        }  

然而,在那些 PC1 和 PC2 IP 地址上,我只得到了无连接状态。 (这意味着这些 IP 无法访问。)

但是当我在我的 Windows 控制台上 ping 它们时,这些 IP 已连接并且 ping 成功。

  1. 我的设置有什么问题。
  2. 我该如何解决这个问题。

【问题讨论】:

  • 你是在unix系统上运行的吗?
  • 不,我在 windows vista basics os 上运行它
  • 成功执行 Windows 控制台 ping 的平均 ping 时间是多少?第一次 ping 时间是多少?如果你的第一次 ping 时间大于 1100,isReachable() 将超时,并返回 false。
  • @Richeve S. Bebedor:我认为 jvm 没有权限执行 ICMP 回显请求,并试图打开与 tcp 端口 7(甚至 udp)的连接作为后备.您可以使用网络嗅探器进行检查吗?
  • @guido 在 Windows 中,如果用户可以从命令行 ping,他也应该能够从 java 发送 ICMP 回显请求。如果这确实失败了,TCP echo 服务在 Windows 上默认不打开,所以它预计会失败(许多 linux 系统今天也出于安全原因阻止了这个)。使用嗅探器应该可以帮助您。

标签: java networking


【解决方案1】:

我相信 guido 在 cmets 中的理论是正确的。见this question。我意识到链接的答案适用于 Linux/UNIX 主机,但我只是在 Windows 7 机器上测试了您的代码,并验证它也将 TCP 数据包发送到 echo 端口 (7) 而不是 ICMP 回显请求。 (我在 Windows 7 机器上的 Java 版本 1.6.0_21 下对此进行了测试,ver 报告了 Microsoft Windows [Version 6.1.7600]

典型的 Windows 机器可能会启用 Windows 防火墙。因此,可能会出现以下事件序列:

  1. 您的 Java 程序(无法发送和接收 ICMP 数据包来测试远程 Windows 主机的可达性)将尝试通过向端口发送 SYN(同步)数据包来启动到远程 Windows 主机的 TCP 连接7
  2. 如果没有服务在该端口上侦听,远程 Windows 主机将丢弃数据包,而不是按照RFC 793 的要求使用 RST 数据包进行响应。也就是说,远程 Windows 主机应该根据 RFC 响应 TCP:
  • RST:如果端口没有监听连接
  • SYN+ACK:如果端口已打开并正在侦听连接
  1. 由于您的 Java 程序期望在步骤 (2) 中发生两件事之一,但根本没有得到任何响应(因为 Windows 在它到达 TCP 堆栈之前丢弃了 SYN 数据包)它错误地假定远程 Windows主机已关闭。

很难说“您的设置问题”是什么。也许什么都没有。这取决于您尝试使用此功能的目的。你可能会以错误的方式去做。您应该意识到ping 并不总是一种 100% 准确的方法来测试主机是否在线。在您的情况下,如果您只对本地网络上的主机感兴趣,那么在尝试 ping 主机后检查 ARP 表可能会更准确。

可能的解决方法:

  • 尝试暂时关闭另一台计算机上的 Windows 防火墙,看看您的代码是否有效。
  • 编写一些执行单独进程的代码,例如运行ping 命令行实用程序来测试可达性。

【讨论】:

  • 不完全。由于连接被 not 完全拒绝并带有这样的数据包,因此 isReachable() 假定主机已关闭。如果它得到一个 RST,它会认为主机是 up.
  • @EJP,我想这就是我所说的。 ;-) 如果您觉得不够清楚,请随时编辑我的答案。
  • @EJP,感谢您的尝试。 ;-) 你激励我完全重写答案的那一部分。现在清楚了吗?
猜你喜欢
  • 1970-01-01
  • 2013-05-25
  • 1970-01-01
  • 2015-06-02
  • 2013-08-21
  • 2016-03-15
  • 2019-12-18
  • 2011-06-01
  • 2012-02-13
相关资源
最近更新 更多