我在Java中实现自己的SocketImplFactory时遇到了一个小问题。我的目标是编写一个工厂,它为我提供了一种通过一个简单的方法调用关闭所有打开的套接字的方法。所以我只想有一种"代理工厂",将所有创建的套接字存储在一个列表中。在此列表中,我可以执行所需的所有操作。
我尝试像这样实现它:
package java.net;
import java.io.IOException;
import java.net.SocketImpl;
import java.net.SocketImplFactory;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.io.IOUtils;
import com.crosscloud.applicationlayer.logger.CCLogger;
public class CCSocketImplFactory implements SocketImplFactory
{
private List<SocketImpl> _openSockets;
public CCSocketImplFactory()
{
_openSockets = new LinkedList<>();
}
@Override
public SocketImpl createSocketImpl()
{
SocketImpl impl = new SocksSocketImpl();
_openSockets.add(impl);
return impl;
}
public void closeAll()
{
_openSockets.forEach((socket)->
{
try
{
socket.close();
}
catch (Exception e)
{
logException(this, e);
}
});
}
public static CCSocketImplFactory register()
{
CCSocketImplFactory fact = new CCSocketImplFactory();
try
{
Socket.setSocketImplFactory(fact);
}
catch (IOException e)
{
logException(CCSocketImplFactory.class, e);
}
return fact;
}
我现在遇到的问题是我必须在包中创建类 java.net 因为类 SocksSocketImpl(在我看来这应该是标准类型)只在这个包中可见。
当我现在想要运行代码时,我得到一个安全异常,因为包名称被禁止。
我的问题有解决方法吗?谢谢!
您似乎只尝试使用java.net
中的一个类 没有必要仅仅为了创建它的实例而移动您的类 tot hat 包。 我建议改用反射。
Constructor cons = Class.forName("java.net.SocksSocketImpl").getDeclaredConstructor();
cons.setAccessible(true);
SocketImpl si = (SocketImpl) cons.newInstance();
但是,默认情况下使用 SOCKS 可能是一个坏主意,因为它不仅会更改套接字的默认值,还会更改所有套接字,甚至是内部使用的套接字,例如 JMX 或 VisualVM。
总是使用 SocksSocketImpl 之外,还有什么替代方案?
我还发现了这个例子,它显示了这种方法的一些扩展可能性。了解当前 Java VM 中打开了哪些网络套接字