我正在用 Java 编写一个端口扫描器,我希望能够区分以下 4 个用例:
- 端口已开放
- 端口已打开,并且已读取服务器横幅
- 端口已关闭
- 服务器未上线
我有以下代码:
InetAddress address = InetAddress.getByName("google.com");
int[] ports = new int[]{21, 22, 23, 80, 443};
for (int i = 0; i < ports.length; i++) {
int port = ports[i];
Socket socket = null;
try {
socket = new Socket(address, port);
socket.setSoTimeout(500);
System.out.println("port " + port + " open");
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String line = reader.readLine();
if (line != null) {
System.out.println(line);
}
socket.close();
} catch (SocketTimeoutException ex) {
// port was open but nothing was read from input stream
ex.printStackTrace();
} catch (ConnectException ex) {
// port is closed
ex.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null && !socket.isClosed()) {
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
问题是,当端口关闭且无法访问服务器时,我都会收到 ConnectionException,但会显示不同的异常消息:
java.net.ConnectException:连接超时:连接
当连接从未建立时
java.net.ConnectException:连接被拒绝:连接
端口关闭时
因此,如果不深入研究实际的异常消息,我就无法区分这两个用例。
当我尝试使用不同的方法创建套接字时,也会发生同样的情况。如果我使用:
socket = new Socket();
socket.setSoTimeout(500);
socket.connect(new InetSocketAddress(address, port), 1000);
我有同样的问题,但有 SocketTimeoutException 。我得到一个
java.net.SocketTimeoutException:读取超时
如果端口已打开,但没有可读取的横幅,并且
java.net.SocketTimeoutException:连接超时
如果服务器不活跃或端口已关闭。
有什么想法吗?提前致谢!
最佳答案
我认为除了解析异常消息之外你没有任何选择。您有什么理由不这样做吗?
关于java - 如何在端口扫描器 java 实现中检测服务器状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2776729/