2011-06-15 52 views
4

我的java代碼使用多個線程,每個線程運行一個ServerSocket並進入接受。這些線程使用java套接字相互通信。隨着121線的所有工作在遠,但如果我有256線程運行相同的代碼,我有這樣的錯誤:Java SocketException:沒有可用的緩衝空間

java.net.SocketException: No buffer space available (maximum connections reached?): listen failed 
    at java.net.PlainSocketImpl.socketListen(Native Method) 
    at java.net.PlainSocketImpl.listen(Unknown Source) 
    at java.net.ServerSocket.bind(Unknown Source) 
    at java.net.ServerSocket.<init>(Unknown Source) 
    at java.net.ServerSocket.<init>(Unknown Source) 

我使用Windows XP SP3,有幾個崗位像這樣(here),但沒有人發表soution對於這個問題。我也安裝了一個Windows補丁,以消除TCP連接的限制,但我沒有解決我的問題。

+0

你是否足夠快地處理傳入連接? – 2011-06-15 19:41:33

回答

4

該消息表示您可能沒有連接。你檢查過了嗎?您可以使用以下命令從命令行檢查打開的套接字:

netstat -n 

確保您關閉了兩側(在finally塊中)的所有套接字。請記住,收到連接後,偵聽套接字保持打開狀態。不要太快地打開和關閉套接字(我會說他們不能立即重用,這可能與您的問題有關)。

爲了獲得更好的與套接字相關的性能,您可以使用java.nio API,但它比java.net複雜得多。

+0

謝謝,我通過更改ServerSocket調用解決了問題。我的錯誤是將積壓值設得太高。我不需要該服務器監聽超過5-6個連接。 我替換: ServerSocket sock = new ServerSocket(port,500); 與 ServerSocket sock = new ServerSocket(port,10); 現在所有的工作都很好! – tulkas85 2011-06-15 21:26:06

3

This post我想可能有你的答案。離開懸空插槽會導致你達到最大值(這可能是由Windows補丁不能修復的其他設置決定的(例如JVM限制?)

作爲一個側面提示,如果您正在運行在很多線程中,很可能你最好使用java.nio而不是java的簡單Socket和ServerSocket類。

This site是一個很好的教程,介紹如何使用java.nio以及如何學習它(連同看Sun/Oracle's Java NIO API),來自使用簡單的Socket和ServerSocket編程。

具體來說,什麼會幫助你的原因是使用選擇器,它會允許您以與C++ select()調用與套接字相同的方式多路複用套接字I/O。這意味着在套接字代碼的核心,可以減少大量線程處理套接字I/O的影響,並且只有一個線程直接與套接字進行交互。

1

我通過更改ServerSocket調用解決了問題。我的錯誤是將積壓值設得太高。我不需要該服務器監聽超過5-6個連接。我替換:ServerSocket sock = new ServerSocket(port,500);使用ServerSocket sock = new ServerSocket(port,10);現在所有的工作都很好!

1

不知道你在做什麼,這只是一個猜測,但我會提供這個,以防其他人看到類似的問題。嘗試打開太多OUTGOING連接時,我看到了此錯誤。通過減少緩衝區大小,限制了連接線程打開的連接數(當達到緩衝區限制時,它們將被拒絕)。如果你仍然有足夠的吞吐量,這是一個很好的解決方案。但是,另一種解決方案是增加可用傳出連接的數量,這可能會解決您的問題並提供更好的吞吐量。

爲此,您可以添加/修改MaxUserPort的註冊表項。使用regedit找到HKEY_LOCAL_MACHINE \系統\ CurrentControlSet \服務\ TCPIP \ Parameters然後添加/修改關鍵:MaxUserPort的輸入DWORD和像65534(十進制)的高值

有一個usoft tech article關於MaxUserPort的。

相關問題