2012-10-07 232 views
0

從冰淇淋三明治升級到果凍豆後,客戶端(Galaxy Nexus)和自定義服務器之間似乎出現時間問題。這裏是一般流程:套接字關閉時間

  1. 客戶端打開插座,問題HTTP GET到服務器
  2. 服務器接受,開始新的線程,與HTTP報頭和200 OK響應。
  3. 服務器將(二進制)文件寫入套接字。
  4. 客戶端從套接字讀取數據並保存到文件。
  5. 服務器線程後寫的所有數據,它關閉套接字,並終止

這比之前的果凍豆更新過去的幾個月中運作良好。自更新以來,二進制傳輸大約70%的時間成功。當'serverSocket.getInputStream()。read'返回一個-1指示已達到流結束時,剩下的30%將失敗 。沒有數據被讀取,未引發錯誤異常,logcat中沒有任何異常。

當我在步驟#5中更改服務器行爲時,會出現計時問題的可能性。線程在寫完觀察到的問題後關閉了套接字。如果我關閉套接字,寫完後終止線程,並讓操作系統最終關閉套接字,然後它似乎一直工作。

我使用tcpdump和WireShark來查看成功和失敗情況下的數據包。在失敗的情況下,套接字在幾毫秒內關閉,而在成功的情況下,套接字關閉的時間爲四分之一秒或更多秒。這是因爲我們在套接字關閉時造成的延遲增加了我們成功的機會。

如果任何人有任何建議與我們可能會導致此問題或建議如何縮小問題,請隨時作出迴應。如果需要,我可以添加代碼示例。

+0

請參閱我編輯的答案。 – Luis

回答

-1

看起來,當服務器要求連接關閉時,套接字立即關閉。也許默認的火箭隊逗留時間在版本之間改變了?

嘗試設置插座盤桓的時間使用:

socket.setSoLinger(boolean on, int timeout); 

讓服務器等待一段時間關閉通道之前,如果一些數據仍然等待發送。

如果不能解決,你可以改變你的流量以上:

...

4.Client從插座中讀取數據並保存到文件中。

5.客戶端向服務器發送確認。

6.服務器關閉連接。

--EDITED-- 一個gracefull方式才達到上述而不考慮關閉確認行駛額外的TCP數據包是:

當服務器完成寫入到插座來電:

socket.shutdownOutput(); 

時客戶端socket.read()返回-1,客戶端調用:

socket.close(); 

這保證了客戶被告知所有的數據已經仙t,並且發送者將等待套接字關閉協議完成。

+0

感謝您的回覆。我們嘗試了沒有區別的流連忘返。它確實有助於證明我們的重試代碼!添加確認是我們試圖避免的。如果我們需要,但現在我們會尋求其他解決方案。 – Dent

+0

你嘗試過「socket.setTcpNoDelay()」嗎? – Luis

+0

我相信setTcpNoDelay()將不起作用。我們的測試案例很小,並且包含在一個包含PSH的單個TCP數據包中。另外,我們對HTTP get的理解,服務器負責首先關閉連接。雖然不違反提出的解決方案,但不符合標準(?)。仍然試圖瞭解它是否是我們的實現或其他。 – Dent