提问人:Saeed Kiarsi Zadeh 提问时间:11/15/2023 更新时间:11/16/2023 访问量:75
为什么会出现此错误:打印异常连接在运行时被拒绝
Why this error Exception print Connection refused on running
问:
看看这个循环。我想做一个小型端口扫描仪的例子。
for (int port = 1; port <= 65300; port++) {
try (Socket socket = new Socket("localhost", port)){
socket.close();
System.out.println("Port " + port + " Listen.");
} catch (UnknownHostException uhe){
System.out.println(uhe.toString());
break;
} catch (Exception e) {
System.out.println("Something went wrong.");
}
}
当我编写代码打印时:System.out.println(e.toString());
java.net.ConnectException: Connection refused (Connection refused)
但是当我删除它时,代码运行良好。如果你知道,告诉我为什么会这样。
谢谢
答:
我不想告诉你这个,但是,你试图这样做的方式将需要很长时间才能通过 65535 个端口。尝试在任何端口的套接字连接上设置超时,以至少在一定程度上加快该过程......大概是 50 毫秒。我想这取决于你拥有的系统。您可以使用 Socket#connect() 方法执行此操作。现在,像 、(或 )这样的 IOException 基本上意味着端口已关闭或根本不可用(对您来说,这也可以被视为已关闭)。生成系统硬件或软件的异常消息或将由系统硬件或软件使用的端口,并且仅针对其特定用途进行保护。connect timed out
Permission denied:
Connection refused
Permission denied:
Connection refused
在我看来,最好的办法是运行扫描考虑几个 ExecutorService 线程(也许像 3000 个),以便在 30 到 40 秒左右完成工作。是的。。。您的盒子会多抽一点血,但是,它胜过等待一整天才能完成端口扫描。
我建议您在扫描过程中不要显示关闭或不可用的端口......这是浪费时间。将输出发送到控制台窗口需要大量不必要的处理时间。只需将开放端口存储在某种集合中,然后在端口扫描完成后将该开放端口集合显示到控制台(或其他任何位置)。下面的可运行演示代码利用了 LinkedHashMap,以便插入到映射中的开放端口号保持插入顺序。
除非您修改代码以运行多个线程,否则我建议您将 int 变量设置为 1000(或 2000),以便更好地了解扫描 65000 个端口需要多长时间。它应该足以给你一些结果(我希望)。portEnd
这是可运行的演示代码。请务必阅读其中的评论:
final int timeout = 50; // Socket Connection timeout in milliseconds
final int portStart = 1; // 1 to 65535
final int portEnd = 65535; // 1 to 65535
final String ip = "127.0.0.1"; // Local IP.
java.util.LinkedHashMap<Integer, String> openPorts = new java.util.LinkedHashMap<>();
System.out.println("Scanning Ports: " + portStart + " To " + portEnd + ". Please Wait!");
System.out.print("Finished Scanning Ports Up To: -> ");
for (int port = portStart; port <= portEnd; port++) {
/* This increases the Scan time but at least
it tells you that something is happenning: */
if (port % 100 == 0) {
System.out.print(port + " ");
}
try (java.net.Socket socket = new java.net.Socket()) {
// Open a connection to the current port Number:
socket.connect(new java.net.InetSocketAddress(ip, port), timeout);
// If successful, then the port is Open. If not, an Exception occurs.
openPorts.put(port, "is Open!");
}
catch (java.io.IOException ex) {
/* This takes time to process as well. It's only here
if for some reason something critical happens: */
String errMsg = ex.getMessage().toLowerCase();
if (!errMsg.contains("connect timed out") &&
!errMsg.contains("permission denied:") &&
!errMsg.contains("connection refused")) {
System.out.println("Port: " + port + " -> *** "
+ ex.getMessage() + " ***");
}
}
}
// Display open ports in Console Window:
System.out.println(System.lineSeparator());
System.out.println("Port Scan Results - Open Ports:");
System.out.println("===============================");
// Read the LinkedHashMap:
for (java.util.Map.Entry<Integer, String> mapElement : openPorts.entrySet()) {
Integer keyPort = mapElement.getKey();
// Finding the value using getValue() method:
String openClosed = mapElement.getValue();
// Print the key-value pairs the way we want:
System.out.println(String.format("Port #%-6d %-8s", keyPort, openClosed));
}
评论
Connection refused (Connection refused)
Permission Denied
IOException
String errMsg = ex.getMessage().toLowerCase(); if (!errMsg.contains("connect timed out") && !errMsg.contains("permission denied:") && !errMsg.contains("connection refused")) { System.out.println("Port: " + port + " -> *** " + ex.getMessage() + " ***"); }
评论
System.out.println(e.toString());
当您删除未打印的邮件时,打印异常消息,但异常仍然发生,只是您没有打印它。如果你对为什么没有打印“Something went wrong.”感到困惑,你需要了解异常捕获是如何工作的,检查 stackoverflow.com/questions/34191745/...Socket socket = new Socket("localhost", port)
new Socket("localhost", port)
UnknownHostException
IOException
UnknownHostException
IOException
Exception
IOException
Exception
IOException