我正在使用ARIN rest whois服务查找组织以获取IP地址列表。由于列表很长(下面的列表只是一个非常小的子集),我选择使用线程来实现更快的性能。
public class SimpleThreadPool {
public final static String[] ips = {
"192.150.16.64","192.243.232.36","208.77.139.8","63.140.35.160",
"63.140.35.161","63.140.35.162","63.140.59.142","63.140.61.200",
"66.235.132.238","66.235.137.133","66.235.138.18","66.235.138.192",
"66.235.138.195","66.235.139.152","66.235.139.172","66.235.139.204",
"66.235.139.205","66.235.139.206","66.235.139.227","66.235.141.144",
"66.235.141.145","66.235.141.146","66.235.141.16","66.235.142.20",
"66.235.142.24","66.235.141.145","184.106.60.35","207.171.162.26",
"207.171.162.75","207.171.162.95","207.171.185.201","207.171.187.117",
"207.171.187.118","207.171.189.80","207.171.189.81","216.137.37.108",
"216.137.37.122","216.137.37.128","216.137.37.138","216.137.37.140",
"216.137.37.178","216.137.37.183","216.137.37.198","216.137.37.225",
"216.137.37.235","216.137.37.37","216.137.37.52","216.137.37.57",
"216.137.37.6","216.137.37.84"
};
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 0; i < ips.length; i++) {
Runnable worker = new WorkerThread(ips[i]);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {}
System.out.println("All threads finished.");
}
}
这是WorkerThread:
public class WorkerThread implements Runnable {
private String workingIP;
public WorkerThread(String workingIP) {
this.workingIP = workingIP;
}
@Override
public void run() {
try {
URL url = new URL("http://whois.arin.net/rest/ip/" + workingIP);
InputStream inputStream = null;
HttpURLConnection con = (HttpURLConnection)(url.openConnection());
con.connect();
inputStream = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line = null;
while( (line=br.readLine()) != null )
{
if (line.contains("<td>Organization</td><td>")) {
String companyName = line.replace("<td>Organization</td><td>", "").trim();
System.out.println(workingIP + " maps to: " + companyName);
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
在我的工作机器上(带有i5-2400,4GB RAM,32位Win7),此代码一直工作到阵列中的第45个+ IP地址。然后我为剩余的查找引发了java.net.ConnectException
个错误:
...
216.137.37.57 maps to: Amazon.com, Inc.
216.137.37.6 maps to: Amazon.com, Inc.
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at sun.net.NetworkClient.doConnect(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.openServer(Unknown Source)
at sun.net.www.http.HttpClient.<init>(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.http.HttpClient.New(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
如果我将执行程序的线程池大小更改为1,那么一切正常并且不会引发错误,但显然查找需要更长的时间。
真奇怪的是,如果我在2011 Core i7 Mac上运行相同的代码,则不会出现任何错误。当然,这两个网络在不同的网络上(我的工作机器使用我的工作网络,而我的Mac无线连接到智能手机)。
知道这里发生了什么,以及我可以做些什么来修复它?
答案 0 :(得分:0)
您需要编写合理的错误处理代码。它真的很简单。如果连接超时,您想要做什么?如果您在慢速网络上一次建立大量连接,其中一些可能会超时。