我有Java代碼在特定端口上設置服務器,某些代碼在使用此服務器的python中運行,然後端口關閉。我已經設置好了,所以在每次python運行後,java循環並重復這個過程(建立一個新的服務器,服務,然後關閉)。將連續的JVM綁定調用限制到同一端口
我注意到,當python調用很短(約爲< 10秒)時,下次Java嘗試設置此端口時,它將失敗。在Java中連續設置相同端口之間需要等待多長時間纔有規則?
我有Java代碼在特定端口上設置服務器,某些代碼在使用此服務器的python中運行,然後端口關閉。我已經設置好了,所以在每次python運行後,java循環並重復這個過程(建立一個新的服務器,服務,然後關閉)。將連續的JVM綁定調用限制到同一端口
我注意到,當python調用很短(約爲< 10秒)時,下次Java嘗試設置此端口時,它將失敗。在Java中連續設置相同端口之間需要等待多長時間纔有規則?
端口可以挑剔這種類型的東西。他們不打算一直打開和關閉。你應該把socket公開,公正的處理中的每個連接,就像這樣:
ServerSocket listener = new ServerSocket(9090);
try {
while (true) {
Socket socket = listener.accept();
try {
PrintWriter out =
new PrintWriter(socket.getOutputStream(), true);
out.println(new Date().toString());
} finally {
socket.close();
}
}
}
finally {
listener.close();
}
不,您應該爲每個傳入連接啓動一個單獨的線程。如果你不這樣做,那麼當你的套接字處理器正在運行時,你的服務器不能做任何事情。 –
@JimGarrison OP一次只暗示一個客戶。如果沒有必要,我認爲沒有理由引入複雜性。 –
@DanielCentore它*是* nessary。對接受的套接字的任何I/O都可以阻塞,如果它在接受線程中完成,則阻塞下一個連接。 – EJP
在一般情況下,最好是維持一個長期運行的ServerSocket
,供應多個請求,正如其他人已經回答和評論的那樣。但是,我發現有時需要快速連續停止和啓動服務器。一個示例是集成測試套件,它涉及停止並重新啓動不同配置的服務器以重複測試運行。
如果您確實有此需求,那麼您可能會對ServerSocket#setReuseAddress(boolean)
感興趣。
啓用/禁用SO_REUSEADDR套接字選項。 當TCP連接關閉時,連接關閉後(通常稱爲TIME_WAIT狀態或2MSL等待狀態),連接可能會保持超時狀態一段時間。對於使用衆所周知的套接字地址或端口的應用程序,如果在涉及套接字地址或端口的超時狀態中存在連接,則可能無法將套接字綁定到所需的套接字地址。
使用bind(SocketAddress)綁定套接字之前啓用SO_REUSEADDR允許套接字被綁定,即使先前的連接處於超時狀態。
這最終啓用了SO_REUSEADDR
套接字選項。有關這些套接字選項的更多詳細信息的一個信息來源是Linux socket
手冊頁。
但是,請注意,確切的感知行爲在不同的平臺上可能會非常大。特別是,請注意MSDN文章Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE中記錄的此設置在Windows上的極端不同且危險的行爲。基本上,Windows上的SO_REUSEADDR
可以允許任意進程「竊取」已被另一進程使用的套接字,從而導致不確定的行爲。
SO_REUSEADDR套接字選項允許套接字強制綁定到另一個套接字使用的端口。第二個套接字調用setsockopt,將optname參數設置爲SO_REUSEADDR,將optval參數設置爲布爾值TRUE,然後調用與原始套接字相同的端口上的綁定。一旦第二個套接字成功綁定,綁定到該端口的所有套接字的行爲就是不確定的。例如,如果同一端口上的所有套接字都提供TCP服務,則通過端口傳入的任何TCP連接請求都無法保證被正確的套接字處理 - 這種行爲是非確定性的。惡意程序可以使用SO_REUSEADDR強制綁定已用於標準網絡協議服務的套接字,以拒絕對這些服務的訪問。使用此選項不需要特殊權限。
我建議人們仔細思考,並確保您對此設置有信心,而不是盲目打開它。還有一個現象之前的問題和答案對相關的套接字選項:
這可能取決於操作系統。 – Robert
通常,您將保持服務器套接字處於打開狀態,並接受並關閉傳入的連接。然後等待同一服務器套接字上的下一個傳入連接。 – Henry