gpt4 book ai didi

java - SocketImpl 和 JUnit/Gradle

转载 作者:行者123 更新时间:2023-12-01 17:29:00 24 4
gpt4 key购买 nike

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

    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 测试中使用相同的代码时,我可以使用 Reflections 检查 Socket.impl.useV4 设置为 true,socksProxy* 设置在系统范围内设置,但是当我使用我的套接字时,它避免使用完全代理(我可以在wireshark中看到它)。

要么是 JUnit,要么是 Gradle,但我已经达到了极限。请建议我下一步应该去哪里。 build.gradle.kts供引用:

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

提前致谢!

最佳答案

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

1) 尽管 Java Socket 支持 Socks v4 作为客户端,但默认情况下并未启用它。并且无法翻转开关。

2)解决了#1之后,我尝试编写E2E测试来解决整个问题,但由于某种原因,它避免进入Socks代理,即使切换(useV4)是真的。这就是我来到这里的SO。

为了解决第一个问题,我实现了 SocketImplFactory (参见上面的问题)。有助于解决这个主题问题的是我的管理背景,尽管它直到最近才开始出现。 :) 我分离了最初的嫌疑人(JUnit 和 Gradle)并在独立的 psvm 文件中进行了测试。测试没有成功,仍然避免了通过代理。这就是我想到的:本地主机的异常(exception)!

基本上,Java 核心库深处存在 localhost(127.0.0.1、::等)的硬编码异常。经过一番搜索后,我发现了 DsocksNonProxyHosts 选项。正如您可能已经猜到的那样,这没有帮助:)最终我得到了 this答案,其中提到我可能需要实现 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 测试我的ocks4 代码,也可以在本地主机上完成它。

关于java - SocketImpl 和 JUnit/Gradle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61160871/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com