2011-10-31 83 views
10

我有一個簡單的服務器客戶端應用程序。一切正常,但在某個階段,從服務器獲得響應需要5分鐘以上(這是正常的,它需要這樣)。問題是,如果超過5分鐘,我會收到這個例外:java.net.SocketTimeoutException: Read timed outJava,增加套接字超時

所以我想知道是否有一些默認套接字超時在Windows上或我可以設置的Java虛擬機?我無法更改客戶端代碼,所以setSoTimeout()不適合我。

使用Windows XP ..

編輯:由於我現在明白的是,插座連接沒有在客戶端打開。它從服務器傳遞。所以我反編譯的服務器jar文件。但仍然無法找到關於超時的任何事情。

+0

檢查是否使用系統屬性配置了超時。 – JimmyB

+0

@HannoBinder,你能解釋一下系統屬性是什麼意思嗎? – hs2d

+0

我的意思是像[sun.net.client.defaultReadTimeout](http://download.oracle.com/javase/1.4.2/docs/guide/net/properties.html)或任何可能適用於您客戶的方式的連接。 – JimmyB

回答

10

默認套接字超時值爲0,表示永不超時。如果5分鐘後實際超時,則意味着它已在代碼中設置。如果源不可用,並且沒有配置,則可以嘗試反編譯該類,然後查找setSoTimeout調用。

由於註釋以及搜索未找到任何setSoTimeout()調用的事實,您可以採取不同的方法。只要讓它超時,並寫一個小腳本,以防萬一它會重試呼叫。如果你可以從命令行調用你的客戶端,你可以解析輸出,如果它發生在stderr上。

+0

我反編譯並尋找'setSoTimeout'調用,但沒有發現任何東西。它必須設置在別的地方呢? – hs2d

8

保持未使用的TCP連接長時間打開並且沒有任何流量並不是那麼簡單。許多防火牆/路由器在超時後關閉未使用的端口。

一個選項可能是實現簡單的keepalive協議來不時發送虛擬數據包,但如果你不能觸摸客戶端代碼,這可能不是一個選項。

編輯:我不知道有什麼方法來覆蓋setSoTimeout()在客戶端代碼中設置。

+0

非常好的主意與保持活着的數據包! – benez

+0

@ benez我不同意。如果路由器將連接看作是一種寶貴的資源,並將其連接起來,那麼您就不會有任何業務欺騙它來保持連接。無論如何,你仍然必須處理連接損失。添加Keepalive乒乓確實是脖子上毫無意義的痛苦。 – EJP

+0

@EJP我還沒有看到適當的實現來處理連接損失。有些情況下您正在等待實時更新,並且您需要不斷連接兩方以保持其數據同步。連接損失不能簡單地通過簡單的重新連接來處理。你會錯過一個重要的信息或遲到。例如股市總是發出心跳,IRC協議要求你用乒乓回答ping。是的,你必須處理連接損失,但你可能想在某些程序中避免它們。 – benez

0

回答說,0是默認超時不完全正確。例如,由於Axis2客戶端具有默認的60秒超時時間,因此它將取決於您使用何種類型的實現進行呼叫。

你能提供更多細節嗎?對不起,寫在答案部分,但我沒有足夠的聲譽做評論:)

+0

看看這裏的代碼,我只能看到'java.io.InputStream'。所以連接必須從服務器到客戶端完成? – hs2d

+0

好吧,是的,對於Java而言,默認值是無限的,但是一個庫可能會改變它。也許是一個提示,hs2d,你有任何jar包括?或者,也許你可以採取不同的方法,只要讓它超時並在失敗時重試。 – stivlo

0

你需要保持連接活着嗎?爲什麼不重新考慮它使它更加異步。該架構根本不能擴展。有一次,所有可用的線程都可能等待服務器的長時間響應。

+0

如果他想從中讀取連接,他需要保持連接正常。無法做出所有這些的頭部或尾部。 – EJP