繁体   English   中英

Java-“没有可用的缓冲区空间”套接字错误原因?

[英]Java - “no buffer space available” socket error cause?

我正在用Java编写网络程序。 我使用ServerSocket和Socket对象使用TCP发送和接收消息。 如果运行时间短,我的程序可以正常运行,但是如果运行时间长,则出现以下错误:

java.net.SocketException: No buffer space available (maximum connections reached?): connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)

我以为可能是因为我没有关闭所有套接字,但是我改变了代码:我有一个类,当我想要一个新的套接字时创建了一个类,并添加了一个finalize方法来关闭它。 我也有一个finalize方法来关闭ServerSocket,所以我不知道问题出在哪里。

同样,在收到错误消息后,如果立即再次运行该程序,它比以前更快地遇到了问题。 然后,如果我稍等片刻然后运行它,它可以恢复为原始时间。

我真的无法解决这个问题,而且我已经尝试了很长时间了。 有谁知道这是什么问题吗?

提前致谢!

更新:

因此,我已经弄清了错误的出处,这真的很奇怪。 我有以下导致问题的代码:

try {
        sock = new Socket(InetAddress.getByName(ipaddr), port);
        sock.close();

        // os = sock.getOutputStream();
        // byte[] arr = s.getBytes();
        // os.write(arr);
        // os.close();

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            sock.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

如您所见,代码应打开一个套接字并对其进行写入。 但是,即使如上所述所有功能代码都已注释掉,因此套接字只是打开然后立即关闭,我仍然会收到“无缓冲区空间”错误。

我真的不知道为什么会这样。 该程序是多线程的,每个线程都使用上述方法定期创建对象并对其进行调用。 当创建和关闭套接字的行被删除时,我不再得到错误,但是当它们在那里时,即使套接字被打开然后立即关闭,我也得到了错误。

有谁知道为什么会这样吗?

非常感谢。

当我想要一个新的套接字并添加一个finalize方法来关闭它时,我创建了一个类。 我也有一个finalize方法来关闭ServerSocket,所以我不知道问题出在哪里。

zz 停止。 校验。 终结器在运行时是不确定的(除非无法再访问该对象,尽管Java应用程序即使终止也可能无法访问!)-请参见销毁和终结 确保您使用的是显式合同(例如Closable并不断地调用它(不要等待GC出现!)。

这个问题最能说明外部资源的“泄漏”-因为GC主要关心内存和内存压力,所以如果压力很小和/或GC不具有攻击性,则很容易首先用尽外部资源,因为终结器尚未运行。 通常,终结器是一个安全网(并不总是起作用),但是不能替代其他形式的外部资源管理。

从上面的链接:

Java不保证何时进行垃圾收集或以什么顺序收集对象。 因此, Java无法保证何时(甚至是否)将调用终结器 ,将以何种顺序调用终结器或将由哪个线程执行终结器。

快乐的编码。

编辑:看到此相关问题: 为什么要实现finalize()? 我喜欢史蒂夫·杰索普(Steve Jessop)的第二反应。

不要使用finalize关闭资源。 它不能可靠地工作。

(有可能资源对象无法尽快完成,并且资源将用完。您无法控制终结器何时运行,并且有可能永远不会运行。)

您应该做的是这样的:

    Resource resource = // allocate resource
    try {
        // Use the resource ...
    } 
    catch (SomeException ...) {
        // Deal with errors from using the resource
    } 
    finally {
        try {
            resource.close()}
        }
        catch (SomeException ...) {
            // Deal with errors from closing the resource
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM