SocketImpl和JUnitGradle。

问题描述 投票:0回答:1

我试图让Socks v4在java.net中开箱即用,而且我似乎已经成功了!我使用的代码是这样的:"Socks v4"。大致上我使用的代码是这样的。

    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;
        }

    }

长话短说, 当我创建一个套接字并传递 -DocksProxyHost和 -DocksProxyPort时, 它就会工作.

我的问题是,当我在junit测试中使用同样的代码时,我可以用Reflections检查Socket.impl.useV4是否设置为true,socksProxy*设置是否在系统范围内,但当我使用我的socket时,它完全避免使用代理(我可以在wireshark中看到它)。

不是JUnit就是Gradle,但我已经到了极限。请教下一步应该怎么做。 build.gradle.kts供参考。

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

先谢谢你!

java gradle junit4
1个回答
0
投票

好吧,我花了太多的时间才弄明白,但我还是弄明白了。我最初的目标是测试我的Socks v4服务器代码,但在路上有两个问题。

1) 尽管Java Socket支持Socks v4作为客户端, 但它并没有被默认启用. 而且没有办法翻转切换。

2)解决了第1个问题后,我试着写了E2E测试来熏陶一下,但不知为什么,它是 避免进入Socks代理即使切换(使用V4)是真的。这是我在SO这里得出的结论。

为了解决第一个问题,我实现了SocketImplFactory(见上面的问题).对解决题目问题有帮助的是我的管理员背景,尽管它直到最近才开始发挥作用:) 我把原来的嫌疑人(JUnit和Gradle)分开,在一个独立的psvm文件中做了测试。测试没有成功,还是避免了通过代理。这时我才恍然大悟:localhost的异常!

基本上,在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));
    }

现在我想要的东西都能用了 我既可以E2E测试我的socks4代码 也可以在本地主机上进行测试

© www.soinside.com 2019 - 2024. All rights reserved.