簡體   English   中英

用jcifs定義的超時不起作用

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM