Java 代理发现机器人

2023-12-24

我编写了一个类 ProxyFinder,它连接到随机 ip 并首先对它们执行 ping 操作,如果它们响应,则尝试通过公共代理端口创建 http 代理连接。

目前,它设置为仅连接到随机 ip。这是相对较快的,每小时发现几个代理。但是,我想以某种方式检查我之前是否已经连接到某个 IP。首先,我尝试将它们保存在一个列表中,但这使用了超过 10GB 的内存。我在下面的代码中包含了一个尝试过的方法,该方法使用 RandomAccessFile 将数据写入缓存,但这在搜索过程中速度非常慢。当每个连接变大时,它会显示整个文件。

我以尽可能小的格式存储数据,每个 ip 仅四个字节。尽管如此,这是 4 * 256 * 256 *256 * 256 字节.. = 16gb 原始内存.. 或每次您想测试另一个 ip 时要搜索的 16gb 文件。

我还尝试创建一个单独的线程来生成 ips,根据文件检查它们,然后将它们添加到探测线程可以从中提取的队列中。它也无法跟上探测线程。

如何快速检查我是否已经连接到某个 IP,而又不会非常慢或使用大量内存?

package net;

import java.io.File;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 * @author Colby
 */
public class ProxyFinder {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {

        int[] ports = {
            1080, 3128, 3128, 8080
        };

        System.out.println("Starting network probe");

        AtomicInteger counter = new AtomicInteger();
        for (int i = 0; i < 500; i++) {
            new Thread(() -> {

                do {
                    try {
                        byte[] addrBytes = randomAddress();//could be getNextAddress also
                        if (addrBytes == null) {
                            break;
                        }

                        InetAddress addr = InetAddress.getByAddress(addrBytes);
                        if (ping(addr)) {
                            float percent = (float) ((counter.get() / (256f * 256f * 256f * 256f)) * 100F);
                            if (counter.incrementAndGet() % 10000 == 0) {
                                System.out.println("Searching " + percent + "% network search");
                            }

                            for (int port : ports) {
                                try {
                                    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(addr, port));

                                    HttpURLConnection con = (HttpURLConnection) new URL("http://google.com").openConnection(proxy);

                                    con.setConnectTimeout(1000);
                                    con.setReadTimeout(1000);
                                    con.setRequestMethod("GET");
                                    con.setRequestProperty("User-Agent", "Mozilla/5.0");

                                    con.getContent();
                                    con.disconnect();

                                    System.out.println("Proxy found!" + addr.getHostAddress() + ":" + port + "  Found at " + percent + "% network search");

                                } catch (Exception e) {
                                }
                            }

                            //
                            //System.out.println("Ping response: --" + addr.getHostAddress() + "-- Attempt: " + counter.get() + " Percent: " + percent + "%");
                        } else {
                            //System.out.println("Ping response failed: " + addr.getHostAddress() + " attempt " + counter.incrementAndGet());
                        }

                    } catch (Exception e) {
                        //e.printStackTrace();
                    }

                } while (true);

            }).start();
        }
    }

    private static RandomAccessFile cache;

    private static byte[] getNextAddress() throws Exception {
        if (cache == null) {
            cache = new RandomAccessFile(File.createTempFile("abc", ".tmp"), "rw");
        }

        byte[] check;
        checkFile:
        {
            byte[] addr = new byte[4];
            do {
                check = randomAddress();
                inner:
                {
                    cache.seek(0);
                    while (cache.length() - cache.getFilePointer() > 0) {
                        cache.readFully(addr);
                        if (Arrays.equals(check, addr)) {
                            break inner;
                        }
                    }
                    cache.write(check);
                    break checkFile;
                }

            } while (true);
        }
        return check;
    }

    private static byte[] randomAddress() {
        return new byte[]{(byte) (Math.random() * 256), (byte) (Math.random() * 256), (byte) (Math.random() * 256), (byte) (Math.random() * 256)};
    }

    private static boolean ping(InetAddress addr) throws Exception {
        return addr.isReachable(500);
    }
}

另外,以防万一有人想知道,我已经让它运行了 12 个小时,它发现了大约 50 个代理,并 ping 了大约 2.09664E-4% 的 IP 范围,即大约 120 万个 ip。对于分配的带宽来说还不错(0.5Mbps)

编辑:我开始认为,存储和检查所有这些 IP 的开销可能比简单地连接到搜索 IP 范围末尾附近的许多重复项还要大。


由于数据量太大,我不会存储整个 IP 地址。将它们存储在数组中BitSet会消耗更少的内存。

edit以前的代码版本已删除,它不正确

下面的版本生成随机地址并将它们保存在文件中。如果找到先前运行的持久性文件,则从该文件中恢复所见地址的信息。

初始版本中未正确处理以下情况:

assuming that no address was already seen
   1.0.0.1 - seen false
   2.0.0.2 - seen false
   2.0.0.1 - seen true, which was wrong and is correctly handled by code below

请参阅代码中的注释以获取更多信息。

public class KeepSeenAddresses {

    static final int FILE_BUFFER_SIZE = 81_920;
    static final int RANGES_SIZE = 256;

    // to store 256 ranges of 255*255*255+1 addresses
    static BitSet[] ranges;

    // Random(1) is taken only for demonstration purpose, so the second
    // application run will find the same seen addresses from previous run
    static Random random = new Random(1);
    // for normal use it's better to have better randomness
    //static Random random = new Random(System.currentTimeMillis());

    public static void main(String[] args)
            throws IOException, ClassNotFoundException {

        if (!readRanges()) {
            initRanges();
        }

        // this case was failing in the initial solution
        // uncomment this block to see how all edge cases
        // which where mentioned in other comments are handled
        /*
         byte[][] addresses = {
             {1, 0, 0, 1}, 
             {2, 0, 0, 2}, 
             {2, 0, 0, 1},
             {1, 2, 3, 4}, 
             {4, 3, 2, 1}, 
             {(byte)128, 0, 0, 0},
             {(byte)255, (byte)255, (byte)255, (byte)255}
         };
         seenAddress(addresses[0]);
         seenAddress(addresses[1]);
         seenAddress(addresses[3]);
         seenAddress(addresses[5]);
         seenAddress(addresses[6]);
         for (byte[] addressBytes : addresses) {
         System.out.printf("seen %s before: %s%n",
         prettyAddress(addressBytes),
         seenBefore(addressBytes)
         );
         }
         */
        processAddresses();

        persistRanges();
    }

    /**
     * Read the seen addresses from a file.
     *
     * @return <code>true</code> if the file was found and has the expected
     * number of ranges, otherwise <code>false</code>
     * @throws IOException
     * @throws ClassNotFoundException
     */
    private static boolean readRanges() throws IOException, ClassNotFoundException {
        File rangesStore = new File("addresses.bin");
        if (!rangesStore.exists()) {
            return false;
        }
        System.out.print("found previous rangesStore... ");
        try (ObjectInputStream ois = new ObjectInputStream(
                new BufferedInputStream(
                        new FileInputStream(rangesStore), FILE_BUFFER_SIZE
                )
        )) {
            ranges = (BitSet[]) ois.readObject();
        }
        if (ranges.length != RANGES_SIZE) {
            System.out.printf("wrong size of rangesStore: expected %d"
                    + "  found: %d%n", RANGES_SIZE, ranges.length);
            return false;
        } else {
            System.out.printf("restored ranges: %d%n", ranges.length);
            return true;
        }
    }

    /**
     * Initialize the address ranges array. All address flags will be set to
     * <code>false</code>.
     */
    private static void initRanges() {
        System.out.print("initialize new rangesStore... ");
        ranges = new BitSet[RANGES_SIZE];
        for (int i = 0; i < RANGES_SIZE; i++) {
            BitSet bitSet = new BitSet(255 * 255 * 255 + 1);
            for (int j = 0; j < 255 * 255 * 255 + 1; j++) {
                bitSet.clear(j);
            }
            ranges[i] = bitSet;
        }
        System.out.printf("initialized ranges: %d%n", RANGES_SIZE);
    }

    /**
     * For demonstration purpose.<br>
     * Generates some random IPv4 addresses. If the address was not seen before
     * the flag for this address will be set to <code>true</code>.
     */
    private static void processAddresses() {
        for (int i = 0; i < 10; i++) {
            byte[] addrBytes = randomAddress();
            boolean seenBefore = seenBefore(addrBytes);
            if (!seenBefore) {
                seenAddress(addrBytes);
                seenBefore = false;
            }
            System.out.printf("seen %s before: %s%n",
                    prettyAddress(addrBytes),
                    seenBefore
            );
        }
    }

    /**
     * Persist the address ranges array. The file size is around 500MB.
     *
     * @throws IOException
     */
    private static void persistRanges() throws IOException {
        System.out.print("persist rangesStore... ");
        try (ObjectOutputStream oos = new ObjectOutputStream(
                new BufferedOutputStream(
                        new FileOutputStream("addresses.bin"), FILE_BUFFER_SIZE)
        )) {
            oos.writeObject(ranges);
        }
        System.out.printf("written ranges: %d%n", ranges.length);
    }

    /**
     * Keep a flag which address has been seen already.
     *
     * @param addrBytes IPv4 address in four bytes
     */
    static void seenAddress(byte[] addrBytes) {
        int rangeIndex = (int) addrBytes[0] & 0xff;
        int rangeOffset = ((int) addrBytes[1] & 0xff * 0xffff)
                + ((int) addrBytes[2] & 0xff * 0xff)
                + ((int) addrBytes[3] & 0xff);
        ranges[rangeIndex].set(rangeOffset);
    }

    /**
     * Check if the passed address was seen before.
     *
     * @param addrBytes IPv4 address in four bytes
     * @return <code>true</code> if the address was seen before, otherwise
     * <code>false</code>
     */
    static boolean seenBefore(byte[] addrBytes) {
        int rangeIndex = (int) addrBytes[0] & 0xff;
        int rangeOffset = ((int) addrBytes[1] & 0xff * 0xffff) + ((int) addrBytes[2] & 0xff * 0xff) + ((int) addrBytes[3] & 0xff);
        return ranges[rangeIndex].get(rangeOffset);
    }

    /**
     * Convert the IPv4 address into pretty string.
     *
     * @param addrBytes IPv4 address in four bytes
     * @return pretty String of the IPv4 address
     */
    static String prettyAddress(byte[] addrBytes) {
        return String.format("%03d.%03d.%03d.%03d",
                (int) addrBytes[0] & 0xff,
                (int) addrBytes[1] & 0xff,
                (int) addrBytes[2] & 0xff,
                (int) addrBytes[3] & 0xff);
    }

    /**
     * Generate a random IPv4 address.
     *
     * @return four bytes of a random generated IPv4 address
     */
    private static byte[] randomAddress() {
        byte[] bytes = new byte[4];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) random.nextInt(256);
        }
        return bytes;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 代理发现机器人 的相关文章

随机推荐

  • QMessageBox.Yes/QMessageBox.No 的值

    我学习 PyQt5 对我来说看起来很复杂 我想知道为什么QMessageBox Yes 或没有 有一些特殊的价值 对我来说是16384 这就是我的意思 from PyQt5 import QApplication QWidget QMess
  • XNA BlendState 与 SpriteBatch

    我们需要一个 BlendState 来充当以下角色 透明 PNG 按预期绘制 保留其后面的任何内容 We use Color White按原样绘制 PNG 我们将改变颜色的 Alpha 通道来改变纹理的 不透明度 为了达到这个效果 Blen
  • 如何正确捕获 WinForms 应用程序中所有未处理的异常

    我想为 WinForms 应用程序中任何线程的所有未处理异常设置处理程序方法 我自己不创建任何应用程序域 根据未处理的异常 https msdn microsoft com en us library system appdomain un
  • Kendo-UI 和 Angularjs 多选选项消失

    我正在使用 Angularjs 和 Kendo UI 当我使用 Kendo ui 多重选择并且我在同一视图上有其他元素时 当我在 我在下面的链接中添加了一个简单的 plunker 演示 要使用它 只需先从多选状态列表中选择一个或多个状态 然
  • 在哪里可以找到用于访问 Exchange/Outlook 联系人和约会的示例 Delphi 代码或组件?

    我需要 Delphi 代码或组件来访问 Exchange Outlook 联系人和约会 我可能需要使用扩展 MAPI 这是为了概念验证 所以我现在还没有准备好花大钱 有什么提示 链接 经验吗 看看这个 在 MS Outlook 中创建约会
  • 如何将具有相同列值的行分组?

    给定具有 3D 空间中的坐标的矩阵和两个矩阵中两个变量 例如 a 和 b 的值 我想将相同点的行合并到一个公共矩阵中 为了清楚地解释这个问题 假设我们有矩阵 A posX posY posZ a and B posX posY posZ b
  • 在 Mahout 0.8 中运行 cvb

    当前的 Mahout 0 8 SNAPSHOT 包括用于主题建模的折叠变分贝叶斯 cvb 版本 并删除了潜在狄利克雷分析 lda 方法 因为 cvb 可以更好地并行化 不幸的是 只有文档lda https cwiki apache org
  • SignalR 请求管道、集线器生命周期

    我从使用 asp net webapi 的 signalR 开始 我试图了解整个 signalR 请求 连接管道以及集线器的生命周期是什么以及谁创建和处置集线器实例 它是否在客户端之间的每次通信上创建 和服务器 原因之一是我们需要了解应该如
  • 文件上传在 jQuery UI 对话框中不起作用

    所以我有一个相当奇怪的问题 我想看看是否有人有一些见解 我有一个页面 其中显示已上传到我们服务器的文件网格 网格工具栏使他们能够上传更多文件 当他们单击工具栏上的 添加文件 按钮时 会出现一个 jQuery UI 对话框模式窗口 其中包含一
  • 在C++中,如何将一个字符串拆分为多个整数? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我有一个由
  • Makefile:英特尔 fortran、文件夹中的源文件和英特尔数学核心函数库

    我在文件夹 ex 中有一个 main f90 f77 子程序文件位于 ex src 中 子程序文件再次使用 BLAS 和 LAPACK 库 对于 BLAS 和 LAPACK 我必须使用 Intel Math Kernel Library I
  • 获取 Facebook 页面选项卡上的用户位置

    可口可乐似乎在这方面做得很好 即使在任何用户交互之前 他们也会设法知道您所在的位置 这适用于 IE 因此不涉及 HTML5 毕竟 Facebook 不会识别navigatorJavaScript 中的对象 他们如何做到这一点 首先 我不认为
  • Sonarqube 未注册任何 C# 问题

    大概类似于这个问题 https stackoverflow com questions 36401757 sonarqube is not registering any c sharp issues 但由于之前的版本已经回答了这个问题 所
  • 匹配多个正则表达式组并删除它们

    我收到了一个文件 我想从中提取有用的数据 文件的格式如下 LINE 1 TOKENKIND somedata TOKENKIND somedata LINE 2 TOKENKIND somedata LINE 3 etc 我想做的是删除 L
  • Tkinter 框架调整大小

    我已经被困了几天 试图弄清楚如何使用这种方法动态调整 TKInter 中的框架大小 class SampleApp tk Tk def init self args kwargs tk Tk init self args kwargs th
  • printf 函数如何处理 %f 规范?

    我有几个程序的输出我无法理解 方案1 include
  • 如何在没有部署描述符的情况下在Spring中注册监听器

    我正在通过 Spring Framework 4 1 0 慢慢步入 Java 世界 需要您在监听器方面的帮助 我创建了没有部署描述符的应用程序 所有与 Spring 相关的配置都在中管理 Configuration带注释的类 一切正常 但我
  • 在多阶段编译中,我们是否应该使用标准的序列化方法来通过阶段传送对象?

    这个问题是在 Scala 3 Dotty 中提出的 但应该推广到 MetaML 系列之外的任何语言 Scala 3 宏教程 https docs scala lang org scala3 reference metaprogramming
  • 如何从 SilverLight 打开 TCP 套接字?

    我需要知道如何从 Silverlight 打开 TCP 套接字连接 它是如何完成的 快速的谷歌搜索提供了这个网站 Silverlight 2 和 System Net Sockets Socket http weblogs asp net
  • Java 代理发现机器人

    我编写了一个类 ProxyFinder 它连接到随机 ip 并首先对它们执行 ping 操作 如果它们响应 则尝试通过公共代理端口创建 http 代理连接 目前 它设置为仅连接到随机 ip 这是相对较快的 每小时发现几个代理 但是 我想以某