以下程序作为TCP客户端,并使用NIO打开套接字连接到远程服务器,如下的Java NIO客户端会导致文件描述符泄漏,只有当远程TCP服务器宕机
private Selector itsSelector;
private SocketChannel itsChannel;
public boolean getConnection(Selector selector, String host, int port)
{
try
{
itsSelector = selector;
itsChannel = SocketChannel.open();
itsChannel.configureBlocking(false);
itsChannel.register(itsSelector, SelectionKey.OP_CONNECT);
itsChannel.connect(new InetSocketAddress(host, port));
if (itsChannel.isConnectionPending())
{
while (!itsChannel.finishConnect())
{
// waiting until connection is finished
}
}
itsChannel.register(itsSelector, SelectionKey.OP_WRITE);
return (itsChannel != null);
}
catch (IOException ex)
{
close();
if(ex instanceof ConnectException)
{
LOGGER.log(Level.WARNING, "The remoteserver cannot be reached");
}
}
}
public void close()
{
try
{
if (itsChannel != null)
{
itsChannel.close();
itsChannel.socket().close();
itsSelector.selectNow();
}
}
catch (IOException e)
{
LOGGER.log(Level.WARNING, "Connection cannot be closed");
}
}
这个程序在Red Hat运行企业Linux服务器版本6.2(Santiago) 当并发套接字的数量处于建立阶段时,文件描述符限制达到最大值,并且在尝试建立更多套接字连接时看到下面的异常。
java.net.SocketException: Too many open files
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
只有当远程节点关闭时,这种情况才会发生,并且当它启动时,一切正常。 当远程TCP服务器关闭,如在上面的代码
java.net.ConnectException: Connection refused: no further information
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source)
如IOException异常处理以下异常被抛出有什么办法强行关闭了底层的文件描述符在这种情况下。 在此先感谢您的帮助。
为什么要配置阻塞false然后阻塞呢? – Neijwiert
根据Javadoc的说法,它应该由nio库自动关闭:“如果连接尝试失败,也就是说,如果调用这个方法抛出一个检查的异常,那么通道将被关闭。” –
@ErwinBolwidt澄清,该文本来自'finishConnect()'的描述,它甚至不应该在这里被调用。 – EJP