我正在使用套接字在java中编写一个简单的应用程序。我最近遇到了一个错误:
java.net.SocketException:打开的文件太多
我现在有几个关于套接字的问题:
我开始想知道如何避免这样的异常?我如何跟踪我的应用程序已经创建了多少套接字文件?什么是限制?
而且,我是正确的假设,socket.close()
方法删除相应的套接字文件?
套接字文件位于何处?这个问题取决于我使用的操作系统吗?因为在Linux中我知道套接字是用文件处理的(就像其他所有东西一样),但我不知道windows等。
答案 0 :(得分:1)
套接字使用文件句柄,你得到的错误意味着你有太多的句柄打开。这可以是使用文件句柄的任何OS资源。它并不意味着你的驱动器上有某个文件(实际上没有套接字)。
在Windows上,您可以在任务管理器,进程视图中查看已打开的句柄数。只需添加列。
在Java中,关闭资源的责任是给打开资源的对象/进程。所以,如果你不打开它,请不要关闭它。如果你打开它,请一直关闭它。
自Java 7以来的最佳做法是永远不要使用object.close(),而是使用Closable
接口和
try( Socket mySocket = new Socket() ) {
// code here
}
这可以保证您的资源将被关闭,并且比
更安全,更易读Socket mySocket = null;
try {
mySocket = new Socket();
} finally {
if ( mySocket != null ) mySocket.close();
}
答案 1 :(得分:1)
我怎么能避免像这样的例外?
socket.close()
。从finally块调用socket.close()
。socket.close()
并不意味着套接字在关闭后可立即重用。它将在MSL的两倍之后重复使用,因为它在关闭后会进入 TIMED_WAIT 状态。因此,如果许多套接字处于 TIMED_WAIT 状态,则应考虑使用connection pool。 我的应用程序已经创建了多少套接字文件?
您可以通过netstat -nalp|grep {pid}|wc
找到这个。
限制是什么?
您可以使用linux中的ulimit -n
找到进程可以打开的最大文件数限制。打开的套接字被视为一个打开的文件。通过模糊/etc/security/limits.conf
文件可以增加此限制。
socket.close()方法是否删除相应的套接字文件?
在linux中是的,当为该套接字调用close()
方法时,将删除套接字文件。
套接字文件在哪里?
在linux中,打开的文件描述符位于/proc/{pid}/fd/
下。我不确定窗户。