当前位置: 首页 > 知识库问答 >
问题:

SocketImpl和JUnit/Gradle

柳修平
2023-03-14

我正在尝试让Socks v4在java中开箱即用。我似乎成功了!我使用的代码大致如下:

    class SocketImplFactorySocks4 implements SocketImplFactory {
        @Override
        public SocketImpl createSocketImpl() {
            System.out.println("Socket implementation triggered");
            try {
                return socketSocks4Factory();
            } catch (Exception e) {
                e.printStackTrace();
                throw new Error("Can't go further");
            }
        }

        private SocketImpl socketSocks4Factory() throws
                [...] {
            Class<?> aClass = Class.forName("java.net.SocksSocketImpl");
            Constructor<?> cons = aClass.getDeclaredConstructor();
            if (!cons.isAccessible())
                cons.setAccessible(true);
            Object socket = cons.newInstance();
            Method method = socket.getClass().getDeclaredMethod("setV4");
            if (!method.isAccessible())
                method.setAccessible(true);
            method.invoke(socket);
            Field field = socket.getClass().getDeclaredField("useV4");
            field.setAccessible(true);
            Object value = field.get(socket);
            return (SocketImpl) socket;
        }

    }

长话短说,当我创建一个套接字并传递-DsocksProxyHost和-DsocksProxyPort时,它就工作了。

我的问题是,当我在junit测试中使用相同的代码时,我可以通过反射检查Socket.impl.useV4设置为true,socksProxy*设置为系统范围,但当我使用我的套接字时,它完全避免使用代理(我可以在wireshark中看到它)。

要么是JUnit要么是Gradle,但我已经达到了极限。请告诉我下一步该去哪里。build.gradle。kts供参考:

tasks{
    test{
        systemProperty("socksProxyHost", "localhost")
        systemProperty("socksProxyPort", "8080")
    }
}

提前感谢!

共有1个答案

郜彬
2023-03-14

嗯,我花了太多时间才弄清楚,但我做到了。我最初的目标是测试我的Socks v4服务器代码,但我在路上遇到了两个问题:

1)尽管Java Socket支持Socks v4作为客户端,但它在默认情况下是不启用的。没有办法扳动开关。

2)解决了#1,我试图编写E2E测试来熏制整个事情,但由于某种原因,它避免了进入Socks代理,即使切换(useV4)是真的。这就是我在SO上带来的。

为了解决第一个问题,我实现了套接字工厂(见上文的问题)。帮助解决这个主题问题的是我的管理背景,尽管它直到最近才开始。:)我将原始嫌疑人(JUnit和Gradle)分开,并在一个独立的psvm文件中进行了测试。测试不起作用,它仍然避免了通过代理。这就是它击中我的时候:本地主机的例外!

基本上,Java核心库中的localhost(127.0.0.1,::,等)有一个硬编码异常。经过一些搜索,我发现了DsocksNonProxyHosts选项。这没有帮助,正如您可能已经猜到的:)最终我得到了这个答案,其中提到我可能需要实现ProxySelector。我做到了:

    static class myProxySelector extends ProxySelector {

    @Override
    public List<Proxy> select(URI uri) {
        List<Proxy> proxyl = new ArrayList<Proxy>(1);
        InetSocketAddress saddr = InetSocketAddress.createUnresolved("localhost", 1080);
        Proxy proxy = SocksProxy.create(saddr, 4);
        proxyl.add(proxy);
        System.out.println("Selecting Proxy for " + uri.toASCIIString());
        return proxyl;
    }

    @Override
    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
        if (uri == null || sa == null || ioe == null) {
            throw new IllegalArgumentException("Arguments can't be null.");
        }
    }
}

整个套接字设置如下所示:

        private void setupSocket() throws IOException {
        Socket.setSocketImplFactory(new SocketImplFactorySocks4());
        ProxySelector proxySelector = new myProxySelector();
        ProxySelector.setDefault(proxySelector);
        proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 1080));
    }

现在我想要的一切都有效:我既能够对我的socks4代码进行端到端测试,又可以在本地主机上完成。

 类似资料:
  • 问题内容: 我直到今天才开始了解Mockito。我写了一些简单的测试(使用JUnit,请参见下文),但是我不知道如何在Spring的托管bean中使用模拟对象。什么是使用Spring的最佳实践。我应该如何向我的bean注入模拟依赖项? 你可以跳过这一步,直到回到我的问题。 首先,我学到了什么。这是一篇很好的文章Mocks Are n’t Stubs,它解释了基础知识(Mock的检查行为验证而不是状

  • 你可以跳过这个直到回到我的问题。 首先,我学到了什么。这是一篇很好的文章,它解释了基础(mock的检查、行为验证,而不是状态验证)。然后有一个很好的例子,这里是Mockito,这里是Mockito更容易的嘲弄。我们解释了mockito的mock对象既是mock又是stub。 在这里Mockito和这里Matchers,你可以找到更多的例子。 我不太明白最后两个环节...有人能给我解释一下Sprin

  • 问题内容: 我已经阅读了Jenkins网站及其JUnit插件,由于某种原因,一些基本的东西对我来说并不明显。 Jenkins有一个插件,可以在运行构建时发送自定义/高级通知电子邮件。在这些电子邮件中,您可以放置​​“ 内容令牌 ”,它们是运行时变量,在生成电子邮件时会被动态值替换。 这些标记之一是 允许您显示已运行或失败的JUnit测试的数量。 如何使Jenkins正确显示此信息?我需要一个插件吗

  • 我在4.10版本中使用junit,在1.3版本中声明了hamcrest核心,在1.3版本中声明了hamcrest库。我的问题是hamcrest库和hamcrest核心是否嵌入junit 4.10。那么junit 4.11呢?

  • 我试图编写一些基本的backingBean测试,但我一直在模仿UserContext和facesContext。 此代码在我尝试测试的代码中: 在另一段代码中,我得到了以下内容: 如何在标准jUnit测试中仅使用mockito来模拟这些?还是必须使用PowerMock之类的工具?

  • 问题内容: Maven模块和之间有什么区别?是否需要在其中包含两个依赖项? 我需要写两个依赖吗 要么 足够? 我是否需要增加对的依赖? 问题答案: 5.4之前的JUnit 从文档: JUnit Jupiter API,用于编写测试和扩展。 JUnit Jupiter测试引擎实现,仅在运行时需要。 JUnit Vintage测试引擎实现,允许在新的JUnit Platform上运行Vintage J