如何使用Java在Windows XP上可靠地扫描SSH端口?

时间:2014-05-24 16:43:05

标签: java tcp windows-xp

我维护了一个用于将软件部署到嵌入式设备的工具。通过不断扫描端口22上应答的任何IP地址,然后打开到该端口的SSH连接来检测这些设备。

在Linux和Windows 7上,此过程适用于20个线程,并且套接字连接上的超时为500毫秒。

不幸的是,我们的某些用户仍然使用Windows XP,而这些设置根本不起作用。具有3000ms超时的单个线程似乎可靠地工作,将线程增加到两个或将超时设置为1000ms会导致一致的故障检测到任何事情 - 所有尝试连接超时(SocketTimeoutException)。

我们尝试在其中一台计算机上应用Event ID 4226 Patcher,但这没有帮助。我们也无法在日志中看到这些事件。

导致此行为的原因是什么,我有什么方法可以解决这个问题?

编辑:用于连接的实际代码是:

try (Socket socket = new Socket()) {
    socket.connect(new InetSocketAddress(address, 22), PORT_SCAN_TIMEOUT);
    LOGGER.trace("Someone is listening on {}:22", address);
} catch (Throwable t) {
    LOGGER.trace("Failed scan on {}", address, t);
    reschedule(address);
    continue;
}

如果此连接成功,则使用JSch创建一个全新的连接。在失败场景中,代码永远不会超出此初始尝试。记录的所有异常都是SocketTimeoutExceptions。

编辑2

我尝试在堆栈中降低一级,只检查主机是否存在,而不是服务器套接字,用以下代码替换上面的代码:

try {
    if(!InetAddresses.forString(address).isReachable(PORT_SCAN_TIMEOUT)) {
        LOGGER.trace("{} not reachable", address);
        reschedule(address);
        continue;
    }
} catch (IOException e) {
    LOGGER.warn("Error trying to check host presence on {}, we will try to connect", e, address);
}

如果由多个线程或快速运行,即使这会失败,但是使用单个线程和3000毫秒超时。针对主机的命令行ping直接返回成功(现在将成为我的后备解决方案)。

编辑3

有了它,它按预期工作(显然只在Windows上):

ProcessBuilder builder = new ProcessBuilder("ping", "-n", "1", address);
try {
    Process process = builder.start();
    process.waitFor();
    return process.exitValue() == 0;
} catch (Throwable t) {
    LOGGER.error("Failed to spawn ping process", t);
    return false;
}

鉴于受影响的机器数量很少,我将使用它,由魔术系统属性切换触发。我仍然对前两种方法可能失败的原因提出任何建议。

1 个答案:

答案 0 :(得分:0)

似乎Windows XP限制了单个进程可以建立的连接数。我的解决方案是应用the nmap page for Windows中描述的注册表更改。之后程序按预期运行。