Java:Threads赢了';t同时发出砰砰声
我正在用Java编写一个简单的网络安全工具。它基本上只需要ping一个可变地址范围并将答案保存在数据库中 起初,我使用了java.net库,但由于它只使用echo命令,打印机、路由器和网络中的一些服务器将无法响应。所以我用了图书馆 由于ping一个254的地址范围大约需要10到15分钟,所以在逐个执行时,我决定使用线程将扫描时间保持在最低限度。但问题是,它仍然一次只ping一个地址 我以前从未使用过线程,因此下面是代码,以防我犯了一个巨大的错误:Java:Threads赢了';t同时发出砰砰声,java,multithreading,echo,ping,icmp,Java,Multithreading,Echo,Ping,Icmp,我正在用Java编写一个简单的网络安全工具。它基本上只需要ping一个可变地址范围并将答案保存在数据库中 起初,我使用了java.net库,但由于它只使用echo命令,打印机、路由器和网络中的一些服务器将无法响应。所以我用了图书馆 由于ping一个254的地址范围大约需要10到15分钟,所以在逐个执行时,我决定使用线程将扫描时间保持在最低限度。但问题是,它仍然一次只ping一个地址 我以前从未使用过线程,因此下面是代码,以防我犯了一个巨大的错误: //the AddressRange class
//the AddressRange class just saves the current address and counts it up by one
AddressRange ar = new AddressRange(tFStart.getText(), tFEnd.getText(), false);
//next() checks, if the last address is reached and returns false, if that is the case
while(ar.next()){
try{
//here, I create and start the threads
new Thread(new Ping(ar.getAddress())).start();
} catch (Exception f) {}
//counts up the address by one
ar.countUp(ar.getAddressBits());
}
这是我的平课:
public class Ping implements Runnable{
private final String address;
public Ping(String address){
this.address = address;
}
@Override
public void run() {
IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest();
request.setHost(address);
try{
IcmpPingResponse response = IcmpPingUtil.executePingRequest(request);
String formattedResponse = IcmpPingUtil.formatResponse(response);
String output = "Destination: " + address + " \n" + formattedResponse + " \n";
if(formattedResponse.contains("Reply")){
InetAddress addr = InetAddress.getByName(address);
output += "Hostname: " + verifyHostName(addr.getHostName()) + " \n";
System.out.println(output);
saveClient(new PingData(output));
}
} catch (Exception f) {}
}
}
当我用java.net库替换icmp4j-时,线程被同时处理。我已经读到,线程不应该访问相同的资源,所以我猜,这就是这里发生的事情。但我太没经验了,无法分析甚至重写库
这是我的Ping类,没有使用icmp4j:
public class Ping implements Runnable{
private final String address;
public Ping(String address){
this.address = address;
}
@Override
public void run() {
try{
InetAddress addr = InetAddress.getByName(address);
if(addr.isReachable()){
String output += "Hostname: " + verifyHostName(addr.getHostName()) + " \n";
System.out.println(output);
saveClient(new PingData(output));
}
} catch (Exception f) {}
}
}
所以我想问,如果我犯了一个错误,或者如果有人有使用上述库的经验,知道如何解决这个问题,或者有一个好的替代方案,那么这项工作完成了
while(ar.next()){
try{
//here, I create and start the threads
new Thread(new Ping(ar.getAddress())).start();
我怀疑您的ar.getAddress()
总是返回相同的地址,因此您只是在创建一组线程ping相同的地址创建大量线程可能会降低性能。线程的最佳数量取决于许多因素,包括操作系统允许JVM使用多少CPU/内核,以及线程所做的工作主要是CPU受限还是I/O受限。甚至很难猜测要使用多少线程,但可以肯定的是254太多了
不要显式地创建线程,而是将
Runnable
任务馈送到线程中。这将使处理线程数变得容易。您甚至可能会发现您的操作系统网络堆栈是瓶颈,使用多个线程根本不会带来任何好处。在icmp4j库中,我注意到,在执行ping请求的Icmp4jUtil类初始化期间,只有基于操作系统的本机网桥的分配是线程安全的,而实际的ping进程执行不是线程安全的。因此,毫无疑问,线程不能同时ping多个地址。它可以ping多个地址。无关:StringBuilder
就是这样一个核心类,它甚至在java.lang
包中。编写自己的类并将其命名为StringBuilder
,这会让任何阅读您的代码的人都感到困惑。谢谢,我不知道这一点。我会改正的我刚刚用多线程编写了ping 140 IP的程序&使用icmp4j库对我来说效果很好,但正如您所说的,java的net库产生了意想不到的结果。在不到一秒钟的时间里,我得到了100个ping结果。您是否收到任何错误或异常?通过逐个删除ping步骤彻底调试!!地址不一样,我敢肯定。我要试试这项服务。听起来它可以解决我的问题。我已经用wireshark对它进行了测试,直到现在,它一次只激活一个ping命令。因此,很难判断网络堆栈是否是问题所在。ThreadPoolExecutor听起来是个好主意,我一定会尝试一下。但由于我不太适合编码,所以可能需要一段时间才能弄明白如何使用那些java.util.concurrent库。但如果你想的话,我会随时通知你。