2017-07-26 52 views
0

我有Java代碼在特定端口上設置服務器,某些代碼在使用此服務器的python中運行,然後端口關閉。我已經設置好了,所以在每次python運行後,java循環並重復這個過程(建立一個新的服務器,服務,然後關閉)。將連續的JVM綁定調用限制到同一端口

我注意到,當python調用很短(約爲< 10秒)時,下次Java嘗試設置此端口時,它將失敗。在Java中連續設置相同端口之間需要等待多長時間纔有規則?

+2

這可能取決於操作系統。 – Robert

+2

通常,您將保持服務器套接字處於打開狀態,並接受並關閉傳入的連接。然後等待同一服務器套接字上的下一個傳入連接。 – Henry

回答

1

端口可以挑剔這種類型的東西。他們不打算一直打開和關閉。你應該把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(); 
    } 

(來源:http://cs.lmu.edu/~ray/notes/javanetexamples/

+1

不,您應該爲每個傳入連接啓動一個單獨的線程。如果你不這樣做,那麼當你的套接字處理器正在運行時,你的服務器不能做任何事情。 –

+2

@JimGarrison OP一次只暗示一個客戶。如果沒有必要,我認爲沒有理由引入複雜性。 –

+0

@DanielCentore它*是* nessary。對接受的套接字的任何I/O都可以阻塞,如果它在接受線程中完成,則阻塞下一個連接。 – EJP

1

在一般情況下,最好是維持一個長期運行的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強制綁定已用於標準網絡協議服務的套接字,以拒絕對這些服務的訪問。使用此選項不需要特殊權限。

我建議人們仔細思考,並確保您對此設置有信心,而不是盲目打開它。還有一個現象之前的問題和答案對相關的套接字選項:

Socket options SO_REUSEADDR and SO_REUSEPORT, how do they differ? Do they mean the same across all major operating systems?

+0

很難理解微軟爲什麼不修正他們的SO_REUSEADDR實現來同意其他人的意見,而不是在整個地方散佈關於它的警告。關於客戶端和服務器綁定到同一端口的以下段落甚至沒有意義。 – EJP

+0

@EJP,很好的問題!也許他們保持全能的向後兼容行爲?我不知道。 –

+0

我懷疑他們可能有一些依賴於這個bug的內部「特性」。 – EJP