[英]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.