2013-10-23 44 views
1

我最近從Windows 8升級到Windows 8.1。在升級之後,我開始遇到與Java中的TCP套接字相關的問題。Windows 8.1上的'卡住'插槽

我工作的應用程序使用Java ServerSocket s,另一個進程連接到該應用程序以發送數據。非常標準的東西,在許多操作系統和Java版本中已經工作了很多年。

在Windows 8.1下,與這些ServerSocket的連接偶爾會「卡住」。這似乎在一定程度上取決於通過套接字一次傳輸的數據量,但是一次發送適度〜1 kB的數據時,它很容易發生。

當插座被「卡住」,發生以下情況:

  • 發送端發送完數據並關閉套接字,並在過程中甚至可以終止。就其而言,數據似乎已成功發送。
  • 接收端通常會獲取部分或全部已發送的數據。但是,在插座的InputStream上調用read時,它永遠不會得到EOF已達到的'-1'指示符。相反,該流程將無限期阻止InputStream.read調用。
  • netstat顯示套接字連接仍然建立到ServerSocket。如果發送數據的進程已終止,則情況更是如此(在這種情況下,netstat -b表明該連接與進程System有關
  • 我試過在系統之間進行連接,問題仍然存在。從CentOS虛擬機(由Win 8.1框託管)連接到Win 8.1框。在這種情況下,'發送'(CentOS)機器上的netstat不會繼續顯示已建立的套接字,而是「接收」(Windows 8.1 )機器確實顯示了已建立的套接字連接
  • 我試着通過回送接口(127.0.0.1)和實際網絡接口(通過指定我的外部可見IP)進行連接,結果相同。

自升級到Windows 8.1以來,我沒有發現任何其他網絡問題。在Windows 8上運行時,相同的代碼正在工作,所以操作系統升級似乎是關鍵。我的環境的細節:

  • 的Windows 8.1 Professional 64位
  • 甲骨文的HotSpot 7u40 JRE(雖然我已經試過7u45和6u37,得到了相同的結果)
  • 戴爾Inspiron 5720
  • 瑞昱正在使用的PCIe FE(有線)網絡適配器

Here is a Gist在我的環境中導致問題的Java測試程序。必須先運行SocketListener。它將打印它綁定的套接字。使用2個參數運行SocketTalker:運行SocketListener的主機,以及與SocketListener綁定的端口。發生問題時,SocketListener會報告新的套接字連接,並且通常至少會收到一些數據。但是,它不報告套接字連接已關閉。

我想這可能是SocketListener包含一個錯誤,但它模擬了在許多Java版本,JRE實現和操作系統中成功運行多年的產品中使用的代碼。

任何技術在Windows調試網絡堆棧將不勝感激。我沒有太大的的Windows開發的...

編輯:

問題的一個樣本的Here is a Wireshark capture。 192.168.1.26是運行SocketTalker的CentOS機器,而192.168.1.9是運行SocketListener的Win 8.1機器。看起來Windows收到數據後就停止響應。我可能在所有事情都說完之前就停止了捕捉,但我認爲我得到了關鍵部分。

+0

檢查是否有更新的Realtek網卡驅動程序......只是一個念頭...... – rolfl

+0

升級到最新的Realtek驅動程序,但不幸的是,這並沒有改變。不過謝謝你的想法。 – Aron

回答

0

您的服務器端從不關閉接受的套接字。這可能會導致任何不良行爲,當然包括ESTABLISHED狀態的持久性。

但是你的Wireshark跟蹤清楚地顯示了一個傳入的FIN和一個傳出的ACK,因此它看起來並不是你描述的行爲的一個實例。請注意,服務器中沒有傳出的FIN,這證明了永不關閉接受的套接字。

注意您的描述非常不準確。 ServerSocket不參與I/O。該連接位於客戶端的Socket和服務器上接受的Socket之間。

+0

關於忘記關閉套接字的公平點 - 我已經添加到我的測試程序,結果沒有改變。請注意,這個問題經常在ServerSocket接受的第一個連接上被重現,因此它從來沒有機會「不關閉」套接字。 SocketListener永遠掛在inputStream.read中,永遠不會收到'-1'返回值。 – Aron

+0

關於Wireshark跟蹤:第6幀看起來是第4幀(PSH)的ACK,而不是第5幀的FIN。這由第7-11幀中的第5幀的重複重試支持。 – Aron