簡體   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