使用Java获取当前网络环境有效的BT Tracker列表
BT Tracker是什么就不介绍了,有兴趣可以百度。
最近在下资源的时候发现种子数量很低,于是产生了想要获取更多的Tracker的想法;网上能搜到不少Tracker列表,但是很难判断是否有效,逐个逐个去验证是否有效工作量太大,于是便有了这个程序。
//普通版
public class TrackerTest {
@SuppressWarnings({"ResultOfMethodCallIgnored"})
public static void main(String[] args) {
final String YOUR_IP_ADDRESS_WORK = "xxx.xxx.xxx.xxx"; //填写你本机的ip地址
final int TIME_OUT = 10000;
TrackerTest trackerTest = new TrackerTest();
StringBuffer result = new StringBuffer();
List<String> lines = new ArrayList<>();
try {
//URL方式读取github上面开源的tracker列表
//https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all.txt
//https://ngosang.github.io/trackerslist/trackers_all.txt
//https://cdn.jsdelivr.net/gh/ngosang/trackerslist@master/trackers_all.txt
URL url = new URL("https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String s;
System.out.println("读取tracker");
while ((s = reader.readLine()) != null) {
if (StringUtils.isNotBlank(s)) {
lines.add(s.trim());
// System.out.println(s);
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
CountDownLatch latch= new CountDownLatch(lines.size());
ExecutorService pool = Executors.newCachedThreadPool();
for (String line : lines) {
String[] hostPort = line.split("/")[2].trim().split(":");
String host = hostPort[0];
//默认端口80
String port = "80";
if (hostPort.length > 1) {
port = hostPort[1];
}
String finalPort = port;
pool.submit(() ->{
try {
if (InetAddress.getByName(host).getHostAddress().equals("127.0.0.1")) {
System.out.println("有内鬼!" + line);
}
if (trackerTest.isReachable(InetAddress.getByName(YOUR_IP_ADDRESS_WORK), InetAddress.getByName(host), Integer.parseInt(finalPort), TIME_OUT)) {
result.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
latch.countDown();//当前线程调用此方法,则计数减一
});
}
FileWriter writer = null;
BufferedWriter out = null;
try {
System.out.println("主线程"+Thread.currentThread().getName()+"等待子线程执行完成...");
latch.await();//阻塞当前线程,直到计数器的值为0
System.out.println("主线程"+Thread.currentThread().getName()+"开始执行...");
System.out.println(result);
File writeName = new File("tracker_output.txt");
writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
writer = new FileWriter(writeName);
out = new BufferedWriter(writer);
out.write(result.toString());
out.flush(); // 把缓存区内容压入文件
} catch (InterruptedException | IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
pool.shutdown();
}
boolean isReachable(InetAddress localInetAddr, InetAddress remoteInetAddr,
int port, int timeout) throws IOException {
boolean isReachable = false;
Socket socket = null;
try {
socket = new Socket();
// 端口号设置为 0 表示在本地挑选一个可用端口进行连接
SocketAddress localSocketAddr = new InetSocketAddress(localInetAddr, 0);
socket.bind(localSocketAddr);
InetSocketAddress endpointSocketAddr =
new InetSocketAddress(remoteInetAddr, port);
long start = System.currentTimeMillis();
socket.connect(endpointSocketAddr, timeout);
System.out.println("SUCCESS - connection established in " + (System.currentTimeMillis()-start) + "ms! Local: " +
localInetAddr.getHostAddress() + " remote: " +
remoteInetAddr.getHostAddress() + " port: " + port);
isReachable = true;
} catch (IOException e) {
System.out.println("FAILURE - CAN not connect! Local: " +
localInetAddr.getHostAddress() + " remote: " +
remoteInetAddr.getHostAddress() + " port: " + port);
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
System.out.println("Error occurred while closing socket..");
}
}
}
return isReachable;
}
}
//定制线程池版
public class ThreadPoolTest {
public static ThreadPoolExecutor executor() {
return new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors() * 2,
Runtime.getRuntime().availableProcessors() * 2,
0L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(512),
//线程创建工厂(priority优先级5,默认)
new ThreadFactoryBuilder().setNameFormat("dbThread-%d").setPriority(5).build(),
//线程池满了之后的拒绝策略 CallerRunsPolicy在任务被拒绝添加后,会用调用execute函数的上层线程去执行被拒绝的任务。
new ThreadPoolExecutor.CallerRunsPolicy());
}
public static void main(String[] args) {
final String YOUR_IP_ADDRESS_WORK = "xx.xx.xx.xx";
final int TIME_OUT = 10000;
List<CompletableFuture<String>> futureList = new ArrayList<>();
ThreadPoolExecutor executor = executor();
try {
//URL方式读取
//https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all.txt
//https://ngosang.github.io/trackerslist/trackers_all.txt
//https://cdn.jsdelivr.net/gh/ngosang/trackerslist@master/trackers_all.txt
URL url = new URL("https://cdn.jsdelivr.net/gh/ngosang/trackerslist@master/trackers_all.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
System.out.println("读取tracker:");
while ((line = reader.readLine()) != null) {
if (StringUtils.isNotBlank(line)) {
String[] hostPort = line.split("/")[2].trim().split(":");
String host = hostPort[0];
//默认端口80
String port = "80";
if (hostPort.length > 1) {
port = hostPort[1];
}
String finalPort = port;
String finalLine = line;
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
try {
if (InetAddress.getByName(host).getHostAddress().equals("127.0.0.1")) {
System.out.println("有内鬼!" + finalLine);
}
if (TrackerTest.isReachable(InetAddress.getByName(YOUR_IP_ADDRESS_WORK), InetAddress.getByName(host), Integer.parseInt(finalPort), TIME_OUT)) {
return finalLine;
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}, executor).exceptionally(throwable -> {
throwable.printStackTrace();
return "";
});
futureList.add(completableFuture);
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("主线程"+Thread.currentThread().getName()+"等待子线程执行完成...");
//completableFuture.join();
CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])).join();
System.out.println("主线程"+Thread.currentThread().getName()+"继续执行");
File writeName = new File("tracker_output.txt");
FileWriter writer = null;
BufferedWriter out = null;
try {
writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
writer = new FileWriter(writeName);
out = new BufferedWriter(writer);
for (CompletableFuture<String> future : futureList) {
String line = future.get();
if (StringUtils.isNotBlank(line)) {
out.write(line);
}
}
out.flush(); // 把缓存区内容压入文件
} catch (IOException | InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
}
}