之前在做ping操作的 时候是想模拟cmd ping的 多线程ping,这样会导致 cpu,内存 暴涨,之后采用的是java中的 InetAddress 类,InetAddress类具有一个缓存,用于存储成功及不成功的主机名解析,
采用方法 public static InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。
public boolean isReachable(NetworkInterface netif, int ttl,int timeout) throws IOException
- 测试是否可以达到该地址。实现尽最大努力试图到达主机,但防火墙和服务器配置可能阻塞请求,使其在某些特定的端口可以访问时处于不可到达状态。如果可以获得权限,则典型实现将使用 ICMP ECHO REQUEST;否则它将试图在目标主机的端口 7 (Echo) 上建立 TCP 连接。 具体用法:
int timeOut = 3000;// 超时应该在3钞以上
boolean status = false;
try {
status = InetAddress.getByName(ip).isReachable(timeOut);//返回true 则表示能ping同
if (status == true) {
log.info("to ping success ip: "+ip);
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
}
多线+队列 ping操作
import java.util.concurrent.ArrayBlockingQueue;
/***
*
* Simple to Introduction
* <p>@ProjectName: </p>
* <p>Copyright:Copyright (c) 2014</p>
* <p>@Package: com.c.net.common.TaskArrayQueue.java </p>
* <p>@ClassName: TaskArrayQueue </p>
* <p>@Description: 队列操作类 </p>
* <p>@Author: wangcj </p>
* <p>@CreateDate: May 10, 2014 10:49:55 AM </p>
* <p>@UpdateUser: wangcj </p>
* <p>@UpdateDate: May 10, 2014 10:49:55 AM </p>
* <p>@UpdateRemark: 说明本次修改内容 </p>
* <p>@Version: v1.0]</p>
*
*/
public class TaskArrayQueue<T> {
private final static int MAX_LIST = 3000;
private ArrayBlockingQueue<T> list_m = new ArrayBlockingQueue<T>(
MAX_LIST);
public synchronized void push(Object ip){
if (list_m != null){
list_m.offer(((T) ip));
}
}
public synchronized T pop(){
T task = null;
if (list_m != null){
if (list_m.size() > 0){
task = list_m.poll();
}
}
return task;
}
public int getSize() {
return list_m.size();
}
}
多线程ping
/****
*
* @author wangcj
* 启动多线程
*/
public class IPServer {
public List<String> startIpServer(String ipsegment, String mask) {
List<String> ips = new ArrayList<String>();
TaskArrayQueue<String> taskArrayQueue = new TaskArrayQueue<String>();
SubNet sbNet = new SubNet(ipsegment, mask, null, null);//把网段、子网掩码传入(192.168.1.2,225.225.225.0) 这主要计算当前网段有多少个可用ip
List<String> iplist = sbNet.getIps();
int ipcount = iplist.size();
if (ipcount == 0) {
return ips;
}
int threadNum = 20;// 线程数
long count = 1;// 每个线程处理的数量
if (ipcount > threadNum) {
count = Math.round(Math.ceil(1.00 * ipcount / threadNum));
}
CountDownLatch latch = new CountDownLatch(threadNum);
List<String> listx = new ArrayList<String>();
for (int i = 1; i <= iplist.size(); i++) {
listx.add(iplist.get(i - 1));
if (i % count == 0) {
PingAndPutIpThread pingAndPutIpThread = new PingAndPutIpThread(taskArrayQueue, listx, latch);
pingAndPutIpThread.start();
listx = new ArrayList<String>();
}
}
if (listx != null && listx.size() > 0) {
PingAndPutIpThread pingAndPutIpThread = new PingAndPutIpThread(taskArrayQueue, listx, latch);
pingAndPutIpThread.start();
}
try {
latch.await(); // 等待所有完成工作
} catch (InterruptedException e) {
e.printStackTrace();
}
while (taskArrayQueue.getSize() > 0) {
String ip = taskArrayQueue.pop();
ips.add(ip);
}
return ips;
}
}
ping操作
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import org.apache.log4j.Logger;
import com.c.net.common.TaskArrayQueue;
public class PingAndPutIpThread extends Thread {
public static Logger log = Logger.getLogger(PingAndPutIpThread.class);
private TaskArrayQueue<String> taskArrayQueue;
private List<String> iplist;
private CountDownLatch latch;
public PingAndPutIpThread(TaskArrayQueue<String> taskArrayQueue,List<String> iplist,CountDownLatch latch) {
this.taskArrayQueue=taskArrayQueue;
this.iplist=iplist;
this.latch = latch;
}
@Override
public void run() {
int timeOut = 3000;// 超时应该在3钞以上
boolean status = false;
try {
for (String ip : iplist) {
status = InetAddress.getByName(ip).isReachable(timeOut);
if (status == true) {
log.info("to ping success ip: "+ip);
taskArrayQueue.push(ip);
}
Thread.sleep(10);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
latch.countDown();//线程完毕,计数器减一
}
}
}
之前采用的是 用多线程ping 把ping通的ip放入队列中,然后在多线程去取队列中的Ip ,放一个 取一个, 队列 先进先出。