簡體   English   中英

Java - 奇怪的掛插座?

[英]Java - Strange hanging socket?

我有一個帶有java服務器的客戶端 - 服務器應用程序。 它的工作非常完美,只是經過一段時間后,突然間,一個插座一直懸掛着。 這個套接字只是其中之一,其余的似乎仍然很好,但一旦進入套接字,服務器就不會超過發送線。 這些是代碼的相關部分:

Socket socket; // A normal socket
out  = new PrintWriter(socket.getOutputStream(), true); // The outstream
out.println(msg + "\0"); // This command is used to send stuff, msg is a String

沒有拋出任何異常,行應用程序似乎沒有超出該行:

out.println(msg + "\0");

我知道String是一個很好的,導致4或5個其他套接字之前,這個可以發送它就好了。 另請注意,據我所知,這個套接字可以在突然掛起之前發送數百條消息。 有誰知道我應該尋找什么樣的錯誤?

有很多事情可能導致這種情況,但聽起來你可能在TCP級別上得到了反壓。

通常,當您在套接字上發送數據時,它只是緩沖並且發送調用(在您的情況下, println()flush() )可以在數據實際發送到網絡之前返回。 可能是您在此套接字上的所有先前寫入都被緩沖到本地SO_SNDBUF ,您只需填寫它。

(1)你能用tcpdump或Wireshark來追蹤它,並找到掛起的確切連接(我知道這很難連接很多)? 在程序掛起時檢查TCP窗口大小將告訴您更多關於是在Java本身還是在網絡級別阻止。

(2)傾倒堆疊並將其貼在這里。 Java套接字有一個內部鎖,可以防止兩個線程同時寫入它們。 您確定在您嘗試寫入時,只有一個線程正在訪問該套接字嗎?

你肯定想嘗試做一個

$ jstack <PID>

當它被凍結以確切地看到它掛在哪里,以及如果寫線程試圖獲得任何鎖定。

Socket對象的OutputStream將在基礎send()調用將阻塞的相同條件下阻塞寫入:當本地套接字緩沖區已滿時。 它保持阻塞狀態表示輸出緩沖區無法清空,這反過來表明連接另一端的讀緩沖區已滿,處理連接另一端的應用程序未讀取已到達的數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM