[英]Timeout defined with jcifs does not work
我已經將responseTimeout和soTimeout設置為15000ms,但是90000ms之后仍然有超時。
我在v1.3.18和v1.3.17上進行了測試。
當我不注冊jcifs時,HttpURLConnection的默認超時在15000ms之后正確發生:
connection.setReadTimeout(15000);
connection.setConnectTimeout(15000);
但是當我注冊jcifs時,在90000ms之后發生了超時:
System.setProperty("jcifs.smb.client.responseTimeout", "15000");
System.setProperty("jcifs.smb.client.soTimeout", "15000");
jcifs.Config.registerSmbURLHandler();
[...]
connection.setReadTimeout(15000);
connection.setConnectTimeout(15000);
看來jcifs超時和我的默認超時都被另一個值忽略了。
我也直接在Config上嘗試過setProperty,但它沒有改變:
jcifs.Config.setProperty("jcifs.smb.client.responseTimeout", "15000");
jcifs.Config.setProperty("jcifs.smb.client.soTimeout", "15000");
(此消息已發布到jcifs論壇,位於http://thread.gmane.org/gmane.network.samba.java/9554 )
對我來說,問題是jcifs包裝了一個新的HttpURLConnection,因此它丟失了在原始連接上定義的所有設置,例如超時設置。 為了證明這一點,我要么使用反射,要么修改庫並更改jcifs內部連接,那么超時可以正常工作。
(有關信息,設置jcifs.smb.client.responseTimeout和jcifs.smb.client.soTimeout不起作用)
首先,我確認jcifs是問題所在:當我使用jcifs.Config.registerSmbURLHandler()時,我的15000ms超時根本不起作用,在30000ms之后連接中斷。 僅當我刪除對registerSmbURLHandler()的調用時,我的15000ms超時才有效。
關於該問題,我打開了一個連接(已預先注冊了jcifs):
URLConnection myConnection = new URL(url).openConnection();
然后,URLStreamHandler創建一個包裝的NtlmHttpURLConnection並隱藏真正的HttpURLConnection:
protected URLConnection openConnection(URL url) throws IOException {
url = new URL(url, url.toExternalForm(),
getDefaultStreamHandler(url.getProtocol()));
return new NtlmHttpURLConnection((HttpURLConnection)
url.openConnection());
}
因此,我的超時設置應用於包裝器NtlmHttpURLConnection,而不應用於真正打開的URLConnection。 所以我的超時是沒有用的:
myConnection.setReadTimeout(15000); // applied to the new NtlmHttpURLConnection(wrapped), not the real wrapped one
myConnection.setConnectTimeout(15000); // applied to the new NtlmHttpURLConnection(wrapped), not the real wrapped one
我可以使用兩種解決方案來更改包裝連接的超時:使用反射或使用固定庫。
通過反射,我訪問私有包裝的連接並更改私有字段connectTimeout和readTimeout:
Class<?> classConnection = myConnection.getClass();
Field privateFieldURLConnection = classConnection.getDeclaredField("connection");
privateFieldURLConnection.setAccessible(true);
URLConnection privateURLConnection = (URLConnection) privateFieldURLConnection.get(myConnection);
Class<?> classURLConnectionPrivate = privateURLConnection.getClass();
Field privateFieldConnectTimeout = classURLConnectionPrivate.getDeclaredField("connectTimeout");
privateFieldConnectTimeout.setAccessible(true);
privateFieldConnectTimeout.setInt(privateURLConnection, 15000);
Field privateFieldReadTimeout = classURLConnectionPrivate.getDeclaredField("readTimeout");
privateFieldReadTimeout.setAccessible(true);
privateFieldReadTimeout.setInt(privateURLConnection, 15000);
或者我修改jcifs庫和構造函數NtlmHttpURLConnection():
public NtlmHttpURLConnection(HttpURLConnection connection) {
super(connection.getURL());
this.connection = connection;
this.connection.setReadTimeout(15000);
this.connection.setConnectTimeout(15000);
requestProperties = new HashMap();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.